WP7 ListBox ItemContainerStyle XAML отключен не работает
У меня есть следующий стиль и список:
<Style x:Key="LwHListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Padding" Value="24, 0, 24, 0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="LayoutRoot" BorderBrush="#FFCCCCCC" BorderThickness="0, 0, 0, 1" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentContainer"/>
<DoubleAnimation Duration="0" To="0.6" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LayoutRoot" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ListBox x:Name="lbxContainer" Height="Auto" Width="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" VerticalAlignment="Top" ItemContainerStyle="{StaticResource LwHListBoxItemStyle}" />
Я использовал Expression Blend для создания стиля. Я хочу, чтобы ListBoxItem имел непрозрачность 60% при отключении. Я заполняю ListBox программно с помощью ListBoxItems, чье свойство IsEnabled установлено на основе определенных критериев. Я прошел через отладчик и подтвердил, что ListBoxItems имеют IsEnabled = false, поэтому я пришел к выводу, что с моим xaml должно быть что-то не так. Есть ли что-то, что я пропускаю или делаю неправильно, из-за чего элементы не становятся непрозрачными при отключении?
ListBox находится на белом фоне и содержит черный текст. Непрозрачность должна сделать его серым. Если я добавлю непрозрачность в нормальное визуальное состояние, оно отобразится как предназначенное для нормального состояния, но также и для состояния Disabled. Я знаю, что отключенные элементы фактически отключены, потому что я не могу нажать на них. Я полагал, что код ниже покажет нормальное состояние как непрозрачные, но отключенные элементы без непрозрачности.
<VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimation Duration="0" To="0.6" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LayoutRoot" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
Обновление: я почти уверен, что что-то не так с моим отключенным состоянием. Ничто из того, что я добавляю в отключенном состоянии, не вступает в силу, даже если я поменяю фон на синий. Я создаю ListBoxItems программно и устанавливаю свойство содержимого для пользовательского элемента управления, который я создал. Может ли это быть причиной проблем? Это не имеет смысла для меня, потому что я могу установить нормальное состояние с непрозрачностью 60%, и это работает, так почему бы не отключить состояние?
2 ответа
Вы не должны использовать ContentControl внутри вашего шаблона управления. Вместо этого вы должны использовать ContentPresenter. Вы можете столкнуться со странными проблемами, если ContentControl отображает содержимое другого ContentControl.
Кроме того, ListBoxItem перейдет в состояние "Отключено", только если ListBoxItem.Content не является элементом управления. Если ListBoxItem.Content является элементом управления, он переходит в состояние "Нормальное", даже если ListBoxItem.IsEnabled имеет значение false.
Вы создали стиль для ListBoxItem, но не для самого ListBox. И вам не обязательно, обязательно. Проблема в том, что по умолчанию ListBox имеет белый фон.
Итак, первый шаг - установить фон ListBox на Transparent, как это...
<ListBox x:Name="lbxContainer" Background="Transparent" Height="Auto" Width="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" VerticalAlignment="Top" ItemContainerStyle="{StaticResource LwHListBoxItemStyle}" />
Тогда я только что сделал пару изменений в вашем стиле ListBoxItem...
<Style x:Key="LwHListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Padding" Value="24, 0, 24, 0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="LayoutRoot" BorderBrush="#FFCCCCCC" Background="{TemplateBinding Background}" BorderThickness="0, 0, 0, 1" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="0.6" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="LayoutRoot" />
<DoubleAnimation Duration="0" To="0.6" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentContainer"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
И теперь, пока контейнер вокруг ListBox не белый, отключенный ListBoxItem должен выглядеть полупрозрачным благодаря настройке Opacity.
Например...
<Grid Background="Black">
<ListBox x:Name="lbxContainer" Background="Transparent" Height="Auto" Width="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" VerticalAlignment="Top" ItemContainerStyle="{StaticResource LwHListBoxItemStyle}">
<ListBoxItem Content="enabled a" />
<ListBoxItem Content="disabled b" IsEnabled="False"/>
<ListBoxItem Content="enabled c"/>
</ListBox>
</Grid>
Будет выглядеть так...