web-dev-qa-db-ja.com

DataTemplateデータ型をインターフェイスにバインドする方法は?

複合疎結合MVVMWPFアプリケーションと親VMの子VMを作成していますVMは、クラスインスタンスではなくインターフェイスです。

public IChildViewModel { get; set; }

DataTemplateを使用してこのプロパティをレンダリングするにはどうすればよいですか?お気に入り:

<DataTemplate DataType="{x:Type contracts:IChildViewModel}">

インターフェイスの性質(多重継承など)により、WPFではこの直接バインドが許可されていないことを理解しています。しかし、インターフェースは疎結合アプリケーションで広く使用する必要があるため、DataTemplateをインターフェースにバインドするための回避策はありますか?ありがとう。

28
Charlie

インターフェイスフィールドにバインドしていることをwpfに明示的に伝えることで、インターフェイスにバインドできます。

(ViewModelBaseは、INotifyPropertyChangedインターフェイスを実装する単なる基本クラスであることに注意してください)

public class Implementation : ViewModelBase, IInterface
{
    private string textField;

    public string TextField
    {
        get
        {
            return textField;
        }
        set
        {
            if (value == textField) return;
            textField = value;
            OnPropertyChanged();
        }
    }
}

public interface IInterface
{
    string TextField { get; set; }
}

次に、ViewModelで:

private IInterface interfaceContent;
public IInterface InterfaceContent
{
    get { return interfaceContent; }
}

そして最後に、それを可能にするXaml:

<ContentControl Grid.Row="1" Grid.Column="0" Content="{Binding InterfaceContent}">
    <ContentControl.ContentTemplate>
        <DataTemplate DataType="{x:Type viewModels:IInterface}">
            <TextBox Text="{Binding Path=(viewModels:IInterface.TextField)}"/>
        </DataTemplate>
    </ContentControl.ContentTemplate>
</ContentControl>

ご覧のとおり、バインディングは「IInterface」定義を明示的に参照しています。

7
t0yk4t

Uwpのデータテンプレートでインターフェイスタイプを使用したバインディングを使用しました。バインディングパスでインターフェイスタイプを明示的に指定しませんでした。インターフェイスが明示的に実装されていない場合に機能しました。インターフェイスが明示的に実装された場合、サイレントに失敗しました。インターフェイスが明示的に実装されている場合は、Bindingがプロパティパスを正しく検索できるように、Bindingパスのインターフェイスタイプへの明示的な参照が必要であると思います。

0
sjb-sjb

このような状況では、DataTemplateSelectorを使用するのが方法のようです。

0
Natxo

インターフェイスを同等の抽象クラスに変換できます。このように機能します。

0
Lamelas84