【问题标题】:How can I use enum types in XAML?如何在 XAML 中使用枚举类型?
【发布时间】:2012-12-26 02:52:58
【问题描述】:

我在学习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>

【问题讨论】:

    标签: c# wpf xaml triggers enums


    【解决方案1】:

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

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

    那么...是的...您必须使用转换器。

    【讨论】:

      【解决方案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>
      

      请注意,您不能在样式中访问 DataTrigger,您需要为此创建 DataTemplate 或 ControlTemplate(但是,.NET 4 添加了在样式中设置触发器的功能)。您可以像这样从 Style 覆盖 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>
      

      对于您希望绑定到对象的 DataTemplate,您可以简单地使用 ContentPresenter 并将其内容设置为您要显示的对象以及用于显示对象的 DataTemplate 定义。总有一种使用 DataTriggers 的方法,它并不总是直接的或像使用样式那样简单。

      【讨论】:

      • 是的,您可以像在此处显示的那样将 Enum 与 XAML 中的 Enum 进行比较,但这个问题是关于将 Enum 与 Integer 进行比较,据我所知,如果没有转换器或自定义,您将无法做到这一点行为。另外,是的,您可以将触发器放在样式中,就像问题示例代码中演示的 OP 一样:)
      • 我没有编辑问题标题的声誉,但我认为标题具有误导性:“我如何在 XAML 中使用枚举类型?”对整数和整数比较只字未提,标题会更清楚的是“我如何在 XAML 中将枚举与整数进行比较?”此外,您不能将 DataTrigger 放在 Style 元素中,普通触发器无法测试绑定。
      • 重要的是阅读整个问题,而不是标题。我真的不想做出改变,因为这是一个老问题,它会把它撞到顶部,但如果这是一个更新的问题,我会的。 :) 另外,也许我误解了你在说什么,但我相当肯定你可以将 DataTriggers 放在 Style.Triggers 中。我一直这样做。
      • 尝试将 DataTrigger 添加到您的 Style.Triggers 集合中。 Visual Studio IDE 和编译器都会抛出错误,让您知道 DataTrigger 不是 Style.Triggers 集合中允许的子项。 DataTriggers 仅在保证存在 DataContext 的地方被有意允许:在 DataTemplate 或 ControlTemplate 中。编辑:显然我错过了 .Net 4.0 和 Visual Studio 2013 中的更改。我的错!
      • 啊,我明白了,我没有意识到这一点。我认为这一定是版本差异或误解之类的,因为您似乎非常确信是这种情况:)
      【解决方案3】:

      我有一个类似的问题here,我的最终结果是创建一个通用的IValueConverter,它传递了我想要匹配的enum 值作为ConverterParameter,它返回true 或@ 987654326@ 取决于绑定值是否与 Enum 的 (int) 值匹配。

      最终结果如下所示:

      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 中导入?
      • @user1696549 您可以在根标记中使用 xmlns 将其他命名空间添加到 XAML。例如,此行会将程序集 MyAssembly 中的命名空间 MyNamespace 添加到 XAML 文件中,并且可以通过前缀 "local" 引用它:xmlns:local="clr-namespace:MyAssembley.MyNamespace;assembly=MyAssembly"
      • 我已成功导入命名空间,但 xaml 告诉我命名空间中不存在“NodeType”...我的命名空间是“XFramework.domain.helpers”,而我的枚举属于 XHelper 类在同一个命名空间中。
      • @user1696549 如果你的枚举在一个名为XHelper的类中,你可能需要使用local:XHelper.NodeType.Type_DB之类的东西
      • 我试过但有错误:不支持嵌套类型!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多