【发布时间】:2010-12-11 18:15:47
【问题描述】:
有没有办法比较触发器的对象类型?
<DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem's Type">
</DataTrigger>
背景:我有一个工具栏,我想根据当前为所选项目对象设置的子类隐藏按钮。
谢谢
【问题讨论】:
标签: wpf xaml types binding datatrigger
有没有办法比较触发器的对象类型?
<DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem's Type">
</DataTrigger>
背景:我有一个工具栏,我想根据当前为所选项目对象设置的子类隐藏按钮。
谢谢
【问题讨论】:
标签: wpf xaml types binding 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 建议的转换器是一个不错的选择。或者,您也可以为每种目标类型使用不同的DataTemplate。 WPF 会自动选择匹配对象类型的DataTemplate
【讨论】:
这是基于@AndyG 的回答,但更安全一些,因为它是强类型的。
实现一个名为 DataTypeConverter 的 IValueConverter,它接受一个对象并返回其类型(作为 System.Type):
public class DataTypeConverter:IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
return value?.GetType() ?? Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}
更改您的 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>
【讨论】:
Binding="{Binding SelectedItem}" Converter={StaticResource DataTypeConverter}}" 应该是Binding="{Binding SelectedItem, Converter={StaticResource DataTypeConverter}}"
不是触发器,但这对我有用。 (触发器方法没有,因为它无法为字符串创建复选框。这几乎是Thomas Levesque's suggestion)
使用:
xmlns:mscorlib="clr-namespace:System;assembly=mscorlib"
取决于类型的 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>
注意:对于 Greg Sansom 的解决方案,您要么将类型返回为 String,要么使用上面的 mscorlib
【讨论】:
如果您可以通过添加属性来修改分配给“SelectedItem”的(基本)类型:
public Type Type => this.GetType();
然后你可以像这样在 xaml 中使用 DataTrigger:
<DataTrigger Binding="{Binding SelectedItem.Type}" Value="{x:Type local:MyClass}">
</DataTrigger>
与 AndyG 的好答案相比的优势在于,您在 XAML 中没有您的类型的魔术字符串,但所有内容都可以安全编译。 缺点:您需要修改模型 - 这可能并不总是可行的。
【讨论】: