Как использовать типы перечислений в XAML?
Я изучаю WPF, и у меня возникла следующая проблема:
У меня есть тип перечисления в другом пространстве имен, кроме моего XAML:
public enum NodeType
{
Type_SYSTEM = 1, // System
Type_DB = 2, // Database
Type_ROOT = 512, // Root folder
Type_FOLDER = 1024, // Folder
}
в моем XAML Я хотел бы запустить изображение с целым числом
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Type}" Value="{NodeType: }">
<Setter Property="Source" Value="/Images/DB.PNG"/>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="128">
<Setter Property="Source" Value="/Images/SERVER.PNG"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
Есть ли способ получить целочисленное значение и сравнить его с типом перечисления непосредственно в коде XAML?
Мое перечисление находится в пространстве имен AnotherNamespace.Types
<DataTrigger Binding="{Binding IntegerType}" Value="MyEnumType.Type_DB">
<Setter Property="Source" Value="/Images/SERVER.PNG"/>
Ответы
Ответ 1
У меня был аналогичный вопрос здесь, и моим конечным результатом было создание родового IValueConverter, которые передали значение enum
, которое я хотел совместить в качестве ConverterParameter
, и оно возвращает true
или false
в зависимости от того, соответствует ли значение привязки значению (int)
для Enum.
Конечный результат выглядит следующим образом:
Код XAML:
<DataTrigger Value="True"
Binding="{Binding SomeIntValue,
Converter={StaticResource IsIntEqualEnumConverter},
ConverterParameter={x:Static local:NodeType.Type_DB}}">
Преобразователь
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (parameter == null || value == null) return false;
if (parameter.GetType().IsEnum && value is int)
{
return (int)parameter == (int)value;
}
return false;
}
Ответ 2
Вам просто нужно убедиться, что ваше пространство имен учитывается в вашем заголовке XAML, тогда вы можете ссылаться как на собственные DP, так и на значения перечисления непосредственно в вашей разметке.
Например, я использую этот код для этого:
<DataTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True" />
<Condition Binding="{Binding Type}" Value="{x:Static loc:AppProfileItemType.Custom}" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="PART_Delete" Property="Visibility" Value="{x:Static Visibility.Visible}" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</DataTemplate.Triggers>
Обратите внимание, что вы не можете получить доступ к DataTriggers в стиле, вам нужно вместо этого сделать DataTemplate или ControlTemplate (однако .NET 4 добавляет возможность устанавливать триггеры в стилях). Вы можете переопределить ControlTemplate из стиля следующим образом:
<Style x:Key="MyCustomButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter />
<ControlTemplate.Triggers>
<!-- Put your DataTriggers here -->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Для DataTemplates вы хотите привязывать объекты к объекту, вы можете просто использовать ContentPresenter и установить его содержимое для объекта, который вы хотите отобразить, вместе с определением DataTemplate, которое будет использоваться для отображения объекта. Всегда есть способ использовать DataTriggers, это просто не всегда прямо или просто, как использование стиля.