web-dev-qa-db-ja.com

オブジェクトタイプに基づくWPFトリガー

トリガーのオブジェクトタイプを比較する方法はありますか?

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

背景:ツールバーがあり、選択した項目オブジェクトに現在設定されているサブクラスに応じてボタンを非表示にしたい。

ありがとう

38
Exist

オブジェクトを取得してオブジェクト型の文字列を返すコンバーターを使用しないのはなぜですか?

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'は、コンバーターがある場所の名前空間です。

お役に立てれば。

35
AndyG

これは@AndyGの回答に基づいていますが、強く型付けされているため、少し安全です。

オブジェクトを受け取り、そのTypeを(System.Typeとして)返すDataTypeConverterという名前のIValueConverterを実装します。

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

DataTriggerを変換してConverterを使用し、値をTypeに設定します。

<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>
49
Greg Sansom

トリガーではありませんが、これでうまくいきました。 (文字列のチェックボックスを作成できないため、トリガーによるアプローチは行われませんでした。これはかなりのことです Thomas Levesqueの提案

使用:

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
mYnDstrEAm

AndyGが提案するコンバーターを使用することは良いオプションです。または、ターゲットタイプごとに異なるDataTemplateを使用することもできます。 WPFはオブジェクトタイプに一致するDataTemplateを自動的に選択します

5
Thomas Levesque

プロパティを追加して、 'SelectedItem'に割り当てられた(ベース)タイプを変更できる場合:

public Type Type => this.GetType();

次に、DataTriggerを次のようにxamlで使用できます。

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

AndyGの良い答えと比較した場合の利点は、XAMLに自分のタイプの魔法の文字列がなく、すべてを安全にコンパイルできることです。欠点:モデルを変更する必要があります-常に可能とは限りません。

0
sa.he