基于对象类型的 WPF 触发器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1652341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:09:15  来源:igfitidea点击:

WPF Trigger based on Object Type

wpfxamltypesbindingdatatrigger

提问by Exist

Is there a way to do a comparison on object type for a trigger?

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

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

Background: I have a Toolbar and I want to Hide button's depending on what subclass is currently set to the selected item object.

背景:我有一个工具栏,我想根据当前设置为所选项目对象的子类来隐藏按钮。

Thanks

谢谢

采纳答案by AndyG

Why not just use a converter that takes an object and returns a string of the object type?

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

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

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

and define the converter as:

并将转换器定义为:

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");
    }
}

You'll need to declare the static resource somewhere in your xaml:

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

<Window.Resources>
    <convs:ObjectToTypeStringConverter x:Key="ObjectToTypeString" />
</Window.Resources>

Where 'convs' in this case is the namespace of where the converter is.

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

Hope this helps.

希望这可以帮助。

回答by Greg Sansom

This is based on @AndyG's answer but is a bit safer because it's strongly typed.

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

Implement an IValueConverter named DataTypeConverter, which accepts an object and returns its Type (as a System.Type):

实现一个名为 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();
    }
}

Change your DataTrigger to use the Converter, and set the value to the Type:

更改您的 DataTrigger 以使用转换器,并将值设置为类型:

<DataTrigger Binding="{Binding SelectedItem,  
      Converter={StaticResource DataTypeConverter}}" 
      Value="{x:Type local:MyType}">
...
</DataTrigger>

Declare DataTypeConverter in the resources:

在资源中声明 DataTypeConverter:

<UserControl.Resources>
    <v:DataTypeConverter x:Key="DataTypeConverter"></v:DataTypeConverter>
</UserControl.Resources>

回答by Thomas Levesque

Using a converter as suggested by AndyG is a good option. Alternatively, you could also use a different DataTemplatefor each target type. WPF will automatically pick the DataTemplatethat matches the object type

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

回答by mYnDstrEAm

Not a trigger but this worked for me. (The trigger-approach didn't as it can't create a checkbox for a string. This is pretty much Thomas Levesque's suggestion)

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

using:

使用:

xmlns:mscorlib="clr-namespace:System;assembly=mscorlib"

? A CheckBox or TextBox depending on the type:

? 一个 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>


Note: for Greg Sansom's solution you either got to return the type as String or use mscorlib as above

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

回答by sa.he

If you are in a position to modify the (base) type assigned to 'SelectedItem' by adding the property:

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

public Type Type => this.GetType();

Then you could use the DataTrigger in xaml like this:

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

<DataTrigger Binding="{Binding SelectedItem.Type}" Value="{x:Type local:MyClass}">
</DataTrigger>

Advantage compared to AndyG's good answer is, that you do not have a magic string of your type in XAML, but have everything compile safe. Disadvantage: You need to modify your model - which might not always be possible.

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