2009-10-30 36 views
34

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

<DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem's Type"> 
</DataTrigger> 

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

感谢

回答

29

为什么不直接使用一个转换器,它接受一个对象,并返回对象类型的字符串?

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'是转换器所在的命名空间。

希望这会有所帮助。

+10

+1为一般的想法,但是转换器应该返回Type对象而不是它的名字...... – 2009-10-31 02:44:01

+2

这样做会工作吗?运行时不会将String类型的东西与Type类型的东西进行比较吗?我知道它处理转换/比较大多数值类型,但不熟悉它如何处理其他类型比较。 – AndyG 2009-10-31 04:30:36

+5

是的,它可以工作,您只需在DataTrigger的值中使用{x:Type}标记扩展。 – 2009-10-31 13:39:15

4

使用AndyG建议的转换器是一个不错的选择。或者,您也可以为每种目标类型使用不同的DataTemplate。 WPF会自动选择DataTemplate与对象类型相匹配

+0

但它也会影响该数据类型的每个子元素 – Staeff 2013-06-25 07:32:17

42

这是基于@ AndyG的回答,但是因为它是强类型的,所以更安全一些。

实施名为DataTypeConverter一个的IValueConverter,它接受一个对象,并返回其类型(作为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(); 
    } 
} 

更改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> 
+1

这对我不起作用。如果我尝试在DataTrigger.Value中使用标记扩展名,我得到一个XamlParseException,所以我刚刚使用了字符串比较方法。请参阅此处:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/14cbdb99-fd33-4ad0-8b1b-a0139c7fbf95/ – RobJohnson 2012-12-04 15:05:50

+3

在尝试GetType()之前,检查值是否为null。返回值!= null? value.GetType():null; – Viv 2013-03-18 17:20:52

+0

'Binding =“{Binding SelectedItem}”Converter = {StaticResource DataTypeConverter}}“'应该是'Binding =”{Binding SelectedItem,Converter = {StaticResource DataTypeConverter}}“' – Firo 2013-08-19 07:06:05

3

不是触发器,但这对我有效。 (该触发器的方法并没有因为它不能创建一个字符串复选框,这是非常Thomas Levesque's suggestion

使用:根据类型

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> 

注:格雷格 - 桑塞姆的解决方案,您要么得返回类型为字符串或使用的mscorlib如上