2

以下は、私が実際にやろうとしていることの簡単な例ですが、それに関する私の質問は同じです。

男性と女性の 2 つのオブジェクトがあり、どちらも同じプロパティ (年齢、身長、体重) を持っていますが、2 つの異なるオブジェクトであるとします。私はそれを変えることはできません。

ここで、特定の男性の年齢をテキスト ボックスに表示する MVVM 原則を使用して作成された WPF パネルがあるとします。そのために Text="{Binding Path=OnePerson.Age}" を使用します。ここで、OnePerson はビューモデルで定義されたタイプ Man のオブジェクトです。

これは問題なく動作しますが、同様のページでこの女性の情報を表示したいと考えています。理想的には、以前と同じビューとビューモデルを使用したいと思います。しかし、データバインディングが Man-object OnePerson を指しているため、これは注意が必要です。プログラムでデータ バインディングを変更できますが ( WPF Binding Programaticallyで説明されているように)、ビューのコード ビハインドからしか変更できません。MVVM モデルを使用しているため、これは許可されていません。

OnePerson に Man オブジェクトまたは Woman オブジェクトを参照させたいのですが、良い方法がわかりません。それらはタイプが異なるため、if ステートメントを使用して単に男性または女性を割り当てることはできません。OnePerson を型ではなくオブジェクトとして宣言することはできますが、そうすると、Age、Height、Weight の各プロパティに簡単にアクセスできなくなります。または、まったく異なる ViewModel を作成し、そのうちの 1 つは OnePerson を男性として宣言し、もう 1 つは女性として宣言し、両方に同じビューを使用することもできます。それはうまくいくと思いますが、1 つのビューに対して 2 つのビューモデルを使用するのは少し奇妙に思えます。そして、独自の Person クラスを追加し、それと Man または Woman の間で変換すると、新しい Man/Women の追加や既存のものの編集などの機能を追加し始めると、おそらくビューモデル全体がかなり複雑になります。

私の質問は、この場合、単一のビューとビューモデルを使用して男性または女性の情報を表示するためのクリーンでシンプルな方法があるかどうかです。それとも、これらの場合のために別のページを作成する必要はありませんか?

これが十分に明確であることを願っています。

4

3 に答える 3

3

ViewModelこれは、ビューやバインディングよりも問題だと思います。はのView視覚的表現のみを意図しており、問題はではなくViewModelで修正する必要があるようです。ViewModelView

WPF のバインド システムは、バインドが無効な場合にのみ警告をスローし、データ型は気にしませんDataContext。質問 ( ) に示されているバインディングは、 が オブジェクトであるか{Binding OnePerson.Age}どうかに関係なく正しく評価され、そのオブジェクトのプロパティの値が表示されます。OnePersonManWomanAge

そのため、最善の解決策は、OnePersonプロパティを aManまたは a のいずれかになる型にすることWomanです。すべての共有プロパティを含むインターフェイスは理想的です。これは、そのプロパティにキャストせずにコードからアクセスでき、既に持っているすべてのバインディングを保持できるためです。

IPerson OnePerson { get; set; }

を使用するよりも共有インターフェイスを使用できない場合は、コードでプロパティを参照する前に、オブジェクトをまたはクラスにobjectキャストすることを忘れないでください。OnePersonManWoman

object OnePerson { get; set; }

...

if (((Man)OnePerson).Age < 0) ...

Man2 つ目の方法は、 用と用の 2 つの個別のプロパティを作成することですWoman。その後、作業しているアイテムのプロパティに から簡単にアクセスできViewModel、ViewModel に単一のビューを使用できます。

Man SomeMan { get; set; }
Woman SomeWoman { get; set; }

ただし、どれが移入されたオブジェクトであるかを識別し、オブジェクトのプロパティを更新するためと、ビューのDataContext

フラグを使用して特定する例を次に示します。DataContext

<Style x:Key="MyContentControlStyle">
    <Setter Property="Content" Value="{Binding SomeMan}" />
    <Style.Triggers>
        <DataTrigger Property="{Binding SelectedPersonType}" Value="Woman">
            <Setter Property="Content" Value="{Binding SomeWoman}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

そしてもちろん、ViewModelオブジェクトの種類ごとに個別のテンプレートを使用したり、個別のテンプレートが必要な場合は、implicit などを使用して各オブジェクトの描画方法を簡単DataTemplatesに決定できます。

<DataTemplate DataType="{x:Type myModels:Man}">
    <myViews:ManUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type myModels:Woman}">
    <myViews:WomanUserControl />
</DataTemplate>

<ContentPresenter Content="{Binding SelectedPerson}" />

全体としてOnePerson、両方のオブジェクトで共有されるデータ型を作成するか、ViewModel両方のオブジェクトに個別に作成することをお勧めします。両方のクラスが非常に似ているように聞こえるので、またはとして渡す場所ViewModelなど、ある種のジェネリックで逃げることさえできるかもしれませんPersonViewModel<T>ManWomanT

于 2013-06-27T13:41:11.243 に答える