Триггер WPF на основе типа объекта - PullRequest
36 голосов
/ 31 октября 2009

Есть ли способ сделать сравнение по типу объекта для триггера?

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

Фон: у меня есть панель инструментов, и я хочу скрыть кнопки в зависимости от того, какой подкласс в настоящее время установлен для выбранного объекта элемента.

Спасибо

Ответы [ 5 ]

47 голосов
/ 11 февраля 2011

Это основано на ответе @ AndyG, но немного безопаснее, потому что оно строго напечатано.

Реализация IValueConverter с именем DataTypeConverter, который принимает объект и возвращает его тип (как 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>
31 голосов
/ 31 октября 2009

Почему бы просто не использовать конвертер, который берет объект и возвращает строку типа объекта?

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' в данном случае - это пространство имен того, где находится конвертер.

Надеюсь, это поможет.

4 голосов
/ 10 сентября 2014

Не триггер, но это сработало для меня. (Триггерный подход не сработал, поскольку не может создать флажок для строки. Это в значительной степени предложение Томаса Левеска )

с помощью:

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>

Примечание: для решения Грега Сансома вы должны либо вернуть тип в виде String, либо использовать mscorlib, как указано выше

4 голосов
/ 31 октября 2009

Использование конвертера, предложенного AndyG, является хорошим вариантом. В качестве альтернативы, вы также можете использовать разные DataTemplate для каждого типа цели. WPF автоматически выберет DataTemplate, соответствующий типу объекта

0 голосов
/ 31 января 2019

Если вы можете изменить (базовый) тип, назначенный для SelectedItem, добавив свойство:

public Type Type => this.GetType();

Тогда вы можете использовать DataTrigger в xaml следующим образом:

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

Преимущество по сравнению с хорошим ответом AndyG заключается в том, что у вас нет магической строки вашего типа в XAML, но все безопасно для компиляции. Недостаток: вам нужно изменить модель, что не всегда возможно.

...