#wpf #xaml #binding #styles
#wpf #xaml #привязка #стили
Вопрос:
Поле со списком, привязанное к словарю (перечисления, строки). Выбранный путь к значению является ключом словаря.
Можно ли установить индивидуальный стиль для каждого элемента поля со списком в XAML?
Ответ №1:
Далее я использую вызываемое пользовательское перечисление Cards
, содержащее константы Skull
, Hearts
и другие для демонстрационных целей. Вместо этого вы можете просто использовать свой тип перечисления.
Стиль контейнера элемента с использованием триггеров данных
Вы можете создать стиль контейнера items с триггерами для каждого значения enum.
<Style x:Key="EnumComboBoxItemStyle" TargetType="{x:Type ComboBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Key}" Value="{x:Static local:Cards.Skull}">
<Setter Property="Foreground" Value="Blue"/>
</DataTrigger>
<DataTrigger Binding="{Binding Key}" Value="{x:Static local:Cards.Hearts}">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
<ComboBox ItemContainerStyle="{StaticResource EnumComboBoxItemStyle}" ...>
Выбор стиля контейнера элемента
Другой вариант — создать селектор стилей, если у вас есть несколько разных стилей, подобных этому:
<Style x:Key="SkullComboBoxItemStyle" TargetType="{x:Type ComboBoxItem}">
<Setter Property="Foreground" Value="Green"/>
</Style>
<Style x:Key="HeartsComboBoxItemStyle" TargetType="{x:Type ComboBoxItem}">
<Setter Property="Foreground" Value="Red"/>
</Style>
<!-- ...other styles. -->
Селектор стилей определяет стиль на основе значения enum .
public class CardsKeyStyleSelector : StyleSelector
{
public override Style SelectStyle(object item, DependencyObject container)
{
if (container is FrameworkElement element amp;amp; item is KeyValuePair<Cards, string> keyValuePair)
{
switch (keyValuePair.Key)
{
case Cards.Skull:
return element.FindResource("SkullComboBoxItemStyle") as Style;
case Cards.Hearts:
return element.FindResource("HeartsComboBoxItemStyle") as Style;
// ...other cases.
}
}
return null;
}
}
Вы можете назначить селектор стиля своему полю со списком, и он выберет правильный стиль.
<ComboBox ...>
<ComboBox.ItemContainerStyleSelector>
<local:CardsKeyStyleSelector/>
</ComboBox.ItemContainerStyleSelector>
</ComboBox>
Комментарии:
1. Хорошо, спасибо! Я тоже нашел решение, используя ItemTemplate со стилем с триггерами. Не требуется никакого кода, кроме словаря и перечисления.
Ответ №2:
Мое решение заключается в следующем. Сначала определите перечислимый тип и словарь, связанный с ним:
Public Enum MyEnum As Integer
OneValue = 0
OtherValue = 1
End Enum
Public ReadOnly Property MyDict As Dictionary(Of MyEnum, String)
Get
Return New Dictionary(Of MyEnum, String) From {
{MyEnum.OneValue, "First value text"},
{MyEnum.OtherValue, "Other value text"}
}
End Get
End Property
Далее, в XAML используйте его следующим образом:
<Style TargetType="Ellipse" x:Key="ellipseStyle">
<Setter Property="Height" Value="10" />
<Setter Property="Width" Value="10" />
<Style.Triggers>
<DataTrigger Binding="{Binding Key}" Value="0"><!-- "0" - one of the dictionary key -->
<Setter Property="Fill" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Key}" Value="1"><!-- "1" - one of the dictionary key -->
<Setter Property="Fill" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type ComboBox}" x:Key="cmb_osn_rez">
<Setter Property="ItemsSource" Value="{Binding MyDict}" />
<Setter Property="SelectedValuePath" Value="Key" />
<Setter Property="ItemsControl.ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Style="{StaticResource ellipseStyle}" />
<TextBlock Text="{Binding Value}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>