Триггер WPF на основе типа объекта
Есть ли способ сделать сравнение по типу объекта для триггера?
<DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem Type">
</DataTrigger>
Фон: у меня есть панель инструментов и я хочу скрыть кнопку в зависимости от того, какой подкласс в данный момент установлен для выбранного объекта объекта.
Спасибо
Ответы
Ответ 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, но все безопасно для компиляции. Недостаток: вам нужно изменить модель, что не всегда возможно.