Подтвердить что ты не робот

Триггер WPF на основе типа объекта

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

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

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

Спасибо

4b9b3361

Ответ 1

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

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

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

Ответ 2

Это основано на ответе @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>

Ответ 3

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

Ответ 4

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

с помощью:

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, как указано выше

Ответ 5

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

public Type Type => this.GetType();

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

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

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