基于对象类型的WPF触发器
有没有办法对触发器的对象类型进行比较基于对象类型的WPF触发器,wpf,xaml,types,binding,datatrigger,Wpf,Xaml,Types,Binding,Datatrigger,有没有办法对触发器的对象类型进行比较 <DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem's Type"> </DataTrigger> 背景:我有一个工具栏,我想隐藏按钮,这取决于当前为所选项目对象设置的子类 谢谢为什么不使用一个转换器来获取一个对象并返回一个对象类型的字符串呢 Binding=“{Binding SelectedItem,Converter={StaticResour
<DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem's Type">
</DataTrigger>
背景:我有一个工具栏,我想隐藏按钮,这取决于当前为所选项目对象设置的子类
谢谢为什么不使用一个转换器来获取一个对象并返回一个对象类型的字符串呢
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");
}
}
您需要在xaml中的某个位置声明静态资源:
<Window.Resources>
<convs:ObjectToTypeStringConverter x:Key="ObjectToTypeString" />
</Window.Resources>
其中,本例中的“convs”是转换器所在位置的命名空间
希望这有帮助。使用AndyG建议的转换器是一个不错的选择。或者,您也可以为每个目标类型使用不同的
数据模板。WPF将自动选择与对象类型匹配的数据模板
,这是基于@AndyG的答案,但因为它是强类型的,所以比较安全
实现名为DataTypeConverter的IValueConverter,它接受对象并返回其类型(作为System.Type):
更改DataTrigger以使用转换器,并将值设置为以下类型:
<DataTrigger Binding="{Binding SelectedItem,
Converter={StaticResource DataTypeConverter}}"
Value="{x:Type local:MyType}">
...
</DataTrigger>
...
在资源中声明DataTypeConverter:
<UserControl.Resources>
<v:DataTypeConverter x:Key="DataTypeConverter"></v:DataTypeConverter>
</UserControl.Resources>
不是触发器,但这对我很有效。(触发器方法没有成功,因为它无法为字符串创建复选框。这非常重要)
使用:
xmlns:mscorlib="clr-namespace:System;assembly=mscorlib"
复选框或文本框取决于类型:
<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>
注意:对于Greg Sansom的解决方案,如果您可以通过添加以下属性来修改分配给“SelectedItem”的(基本)类型,则您可以将类型返回为字符串,或者如上所述使用mscorlib:
public Type Type => this.GetType();
然后可以在xaml中使用DataTrigger,如下所示:
<DataTrigger Binding="{Binding SelectedItem.Type}" Value="{x:Type local:MyClass}">
</DataTrigger>
与AndyG的好答案相比,它的优点是,您在XAML中没有您的类型的神奇字符串,但所有内容都可以安全编译。
缺点:您需要修改您的模型-这可能并不总是可能的。+1一般来说,转换器应该返回类型对象而不是它的名称…这样行吗?运行时不会将字符串类型的内容与字符串类型的内容进行比较吗?我知道它可以处理大多数值类型的转换/比较,但不熟悉它如何处理其他类型的比较。是的,它可以工作,您只需要在DataTrigger的值中使用{x:Type}标记扩展。这对我不起作用。如果我尝试在DataTrigger.Value中使用标记扩展名,我会得到一个XamlParseException,因此我只使用了字符串比较方法。请参见此处:在尝试GetType()之前,最好检查值是否为null。返回值!=无效的value.GetType():nullBinding=“{Binding SelectedItem}”Converter={StaticResource DataTypeConverter}}”
应该是Binding=“{Binding SelectedItem,Converter={StaticResource DataTypeConverter}”
但它也会影响该数据类型的每个子元素
<DataTrigger Binding="{Binding SelectedItem.Type}" Value="{x:Type local:MyClass}">
</DataTrigger>