1

私のコードを見て、私のベースクラスの多くが、バインドされたオブジェクトのプロパティをDataTemplateSelectorチェックするなど、ほとんど同じことをしていることに気付きました。bool私は、ほとんど同じことをするオブジェクトをたくさん作りたいとは思っていませんが、自分のアイデアに完全に満足しているわけではありません。

私が最も気に入っているアイデアは、必要なオブジェクトをテンプレートにバインドし、テンプレートを選択するために使用するブール型プロパティなどの名前DataTemplateSelectorに設定できるプロパティを持たせることです(セレクタをインスタンス化するときに名前を指定します) my xaml. セレクターでは、リフレクションを使用してプロパティにアクセスします。

2 番目のアイデアは、ブール値のプロパティをバインドし、テンプレートで先祖への相対バインディングを使用して、DataContextそこから作業することです。私はこれが好きではありません.

この目的のためにインターフェイスを実装することもできますが (ブール値のプロパティが常に同じ名前になるようにするため)、これはモデル内にビュー専用のコードが含まれることを意味します。または、インターフェイスを a に実装し、同じコントロールでこれViewModelを複数実行することはできませんDataTemplateSelector(この目的のためだけにクラスに分割する必要はありません)。

名前でバインドするだけです。非常に単純なソリューションですが、テンプレートを複数のコントロールで再利用する場合は実際には機能しません。UserControlたとえば、テンプレートが必要な場所が1つある場合に使用するソリューション。これをリソースにUserControlして、シンプルで保守可能なソリューションを用意してください。テンプレートを複数のコントロールで使用したくない限り、まったく問題ありません。

私が見落としている他のアイデアはありますか?上記の内容について何かコメントはありますか?

明確化のためのコード例

注意: 私はオフィスにいないため、コンパイラを使用せずにコードを入力しました。この問題を説明する必要があるため、コンパイル エラーなどはあまり重要ではありません。

私が話しているモデルのストリップバージョン:

public class RegisterToRead : IValueNotifyPropertyChanged
{
    ...
    public bool UseName { get {...} set {...} }
}

私の典型的なTemplateSelectors の1 つ

public class RegisterToReadTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, 
        DependencyObject container)
    {
        if(item != null && item is RegisterToRead)
        {
            RegisterToRead register = (RegisterToRead)item;

            if( register.UseName)
                return element.FindResource("nameSelectionTemplate") as DataTemplate;
            else
                return element.FindResource("manualEntryTemplate") as DataTemplate;
        }
        return null;
    }
}

できないけど、精神的にやりたいこと

TemplateSelector次のようなaを用意します。

public class BooleanTemplateSelector : DataTemplateSelector
{
    public property DataTemplate TrueTemplate { get; set; }
    public property DataTemplate FalseTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, 
        DependencyObject container)
    {
        if(item != null && item is bool)
        {
            bool value = (bool)item;

            if( value)
                return TrueTemplate;
            else
                return FalseTemplate;
        }
        return null;
    }
}

そして、このように使用して、上記の効果を達成します。

<sel:BooleanTemplateSelector
     TrueTemplate="{StaticResource nameSelectionTemplate}" 
     FalseTemplate="{StaticResource manualEntryTemplate}" 
     x:Key="RegisterToReadTemplateSelector" />
<ContentPresenter Content="{Binding SelectedRegister.UseName}" 
    ContentTemplateSelector={StaticResource ResourceKey=RegisterToReadTemplateSelector}"/>

しかしDataContext、テンプレートの内部が UseName プロパティに設定されるため、これはできません。これは私が望むものではありません。

この質問にはスタックオーバーフローに関する重複があります: ContentTemplateSelector の Bind プロパティですが、DataContext をテンプレートに渡しますが、OP は何の回答も得られず、4 番目のアイデアに行きました。私が投稿した他のアイデアについてもフィードバックを得るため、質問をもう一度述べたいと思います。

4

0 に答える 0