如何在XAML中使用枚举类型?

44

我正在学习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"/> 
</DataTrigger>
3个回答

67

我有一个类似的问题here,我的最终解决方案是创建了一个通用的IValueConverter,将我想要匹配的enum值作为ConverterParameter传递,并根据绑定值是否与枚举的(int)值匹配返回truefalse

最终结果如下:

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;
}

谢谢回复!如果我的“NodeType”在另一个命名空间中,我该如何在xaml中导入? - davymartu
1
我已经成功导入命名空间,但 XAML 告诉我在该命名空间中 "NodeType" 不存在。我的命名空间是 "XFramework.domain.helpers",我的枚举类型位于同一命名空间下的 XHelper 类中。 - davymartu
@user1696549 如果你的枚举在名为 XHelper 的类中,你可能需要使用类似于 local:XHelper.NodeType.Type_DB 的东西。 - Rachel
@user1696549 嗯,我记得在某个地方看到过 x:Static 只支持两个级别,所以 local:Class.Property 是可以的,但是 local:Class.Property.SubProperty 不行。尝试使用 {x:Type local:XHelper.NodeType.Type_DB} 作为你的 ConverterParameter - Rachel
这似乎是一个简单问题的过度复杂解决方案。您可以在XAML内进行直接比较,无需任何自定义转换器或标记扩展。请参见下面的答案。 - tpartee
显示剩余2条评论

17

只需确保您的命名空间在XAML头中得到考虑,然后您就可以直接在标记中引用自定义依赖属性和枚举值。

例如,我使用以下代码来实现此操作:

<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,只是不总是直接或像使用样式那样简单。


1
是的,您可以像您在此处显示的那样在XAML中将枚举与枚举进行比较,但是这个问题是关于将枚举与整数进行比较,据我所知,您不能这样做,除非使用转换器或自定义行为。另外,是的,您可以像OP在问题的示例代码中演示的那样在样式中放置触发器 :) - Rachel
1
我没有足够的声望来编辑问题标题,但我认为标题是误导性的:“如何在XAML中使用枚举类型?”并没有涉及整数和整数比较,标题应该更清晰,即“如何在XAML中将枚举与整数进行比较?”此外,在Style元素中无法放置DataTrigger,普通的Triggers无法测试绑定。 - tpartee
重要的是要读整个问题,而不只是标题。我不想做出改变,因为这是一个旧问题,会将其推到顶部,但如果这是一个新问题,我会这样做。:) 另外,也许我误解了你的意思,但我非常肯定你可以在Style.Triggers中放置DataTriggers。我经常这样做。 - Rachel
尝试将DataTrigger添加到Style.Triggers集合中。Visual Studio IDE和编译器都会抛出错误,让您知道DataTrigger不是Style.Triggers集合中允许的子元素。 DataTriggers只允许在保证存在DataContext的位置使用:在DataTemplate或ControlTemplate中。编辑:显然我错过了这个在.Net 4.0和Visual Studio 2013中更改的内容。我的错! - tpartee
@tpartee:您能否添加上述方程的C#端?我在尝试将一个作为枚举实例的C#类成员变量与我的XAML代码联系起来时遇到了麻烦,具体来说是为了触发一组Setter更改DataGrid定义中Style内的DataGridCell的特性。我对C#和WPF(当然还有XAML)都很陌生,每个人的答案总是省略关键细节(通常是在C#方面),假设读者可以填补空白。如果您有时间,能否回答我的问题?... http://stackoverflow.com/q/31615946/1245420 - phonetagger
显示剩余2条评论

4

生活没有必要如此复杂。Enum可以很容易地转换为字符串,因此您可以在触发器中使用该字符串值。

<Image.Style>
    <Style TargetType="{x:Type Image}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Type}" Value="Type_DB">
                <Setter Property="Source" Value="/Images/DB.PNG"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Type}" Value="Type_SERVER">
                <Setter Property="Source" Value="/Images/SERVER.PNG"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Image.Style>

但是如果您将int值存储在枚举中...因为您可以进行分配:

NodeType val = (NodeType)619;

然后...是的...你必须使用转换器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接