WPF触发器基于对象类型

Exi*_*ist 36 wpf xaml binding types datatrigger

有没有办法对触发器的对象类型进行比较?

<DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem's Type">
</DataTrigger>
Run Code Online (Sandbox Code Playgroud)

背景:我有一个工具栏,我想要隐藏按钮,具体取决于当前为所选项目对象设置的子类.

谢谢

Gre*_*som 48

这是基于@AndyG的答案,但有点安全,因为它是强类型的.

实现名为DataTypeConverter的IValueConverter,它接受一个对象并返回其Type(作为System.Type):

public class DataTypeConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
      CultureInfo culture)
    {
        return value.GetType();
    }

    public object ConvertBack(object value, Type targetType, object parameter,
      CultureInfo culture)
    {
       throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

更改DataTrigger以使用Converter,并将值设置为Type:

<DataTrigger Binding="{Binding SelectedItem,  
      Converter={StaticResource DataTypeConverter}}" 
      Value="{x:Type local:MyType}">
...
</DataTrigger>
Run Code Online (Sandbox Code Playgroud)

在资源中声明DataTypeConverter:

<UserControl.Resources>
    <v:DataTypeConverter x:Key="DataTypeConverter"></v:DataTypeConverter>
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)

  • 在尝试GetType()之前,最好先检查value是否为null.返回值!= null?value.GetType():null; (5认同)

And*_*dyG 33

为什么不使用一个转换器来获取一个对象并返回一个对象类型的字符串?

Binding="{Binding SelectedItem, Converter={StaticResource ObjectToTypeString}}"

并将转换器定义为:

public class ObjectToTypeStringConverter : IValueConverter
{
    public object Convert(
     object value, Type targetType,
     object parameter, System.Globalization.CultureInfo culture)
    {
        return value.GetType().Name;            
    }

    public object ConvertBack(
     object value, Type targetType,
     object parameter, System.Globalization.CultureInfo culture)
    {
        // I don't think you'll need this
        throw new Exception("Can't convert back");
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要在xaml中的某处声明静态资源:

<Window.Resources>
    <convs:ObjectToTypeStringConverter x:Key="ObjectToTypeString" />
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,'convs'是转换器所在的命名空间.

希望这可以帮助.

  • 一般的想法+1,但转换器应返回Type对象而不是其名称... (13认同)
  • 是的,它可以工作,你只需要在DataTrigger的值中使用{x:Type}标记扩展. (6认同)
  • 那会有用吗?运行时不会将类型为String的类型与Type类型进行比较吗?我知道它处理转换/比较大多数值类型但不熟悉它如何处理其他类型比较. (2认同)

Tho*_*que 5

按照AndyG的建议使用转换器是一个不错的选择。另外,您也可以DataTemplate为每个目标类型使用不同的名称。WPF将自动选择DataTemplate与对象类型匹配的


mYn*_*EAm 5

不是触发器,但这对我有用。(触发器方法没有,因为它无法为字符串创建复选框。这几乎是Thomas Levesque的建议

使用:

xmlns:mscorlib="clr-namespace:System;assembly=mscorlib"
Run Code Online (Sandbox Code Playgroud)

  一个CheckBox或TextBox取决于类型:

<ContentPresenter Content="{TemplateBinding SelectedItem}">
      <ContentPresenter.Resources>
               <DataTemplate DataType="{x:Type mscorlib:Boolean}">
                    <CheckBox Height="25" Width="25" HorizontalAlignment="Left" IsChecked="{Binding Path=.}"/>
               </DataTemplate>
                  <DataTemplate DataType="{x:Type mscorlib:String}">
                    <TextBox Height="25" Width="200" HorizontalAlignment="Left" Text="{Binding Path=.}"/>
                </DataTemplate>
       </ContentPresenter.Resources>
</ContentPresenter>
Run Code Online (Sandbox Code Playgroud)

注意:对于Greg Sansom的解决方案,您必须将类型返回为String或如上所述使用mscorlib


sa.*_*.he 5

如果您可以通过添加属性来修改分配给“SelectedItem”的(基本)类型:

public Type Type => this.GetType();
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样在xaml中使用DataTrigger:

<DataTrigger Binding="{Binding SelectedItem.Type}" Value="{x:Type local:MyClass}">
</DataTrigger>
Run Code Online (Sandbox Code Playgroud)

与 AndyG 的良好答案相比,优点是,您在 XAML 中没有类型的魔术字符串,但所有内容都可以安全编译。缺点:您需要修改模型 - 这可能并不总是可行。