アプリケーションアーキテクチャをビュー間の関係として図化しているとは思えません。私は、それを考える良い方法は、必要に応じてツリーから垂れ下がったビューを使って、ビューモデル間の関係のセットとして考えることです。そのように考えると、「データはどのように受け継がれますか」がずっと簡単になります。ビューは、ビューモデルとユーザーの間の単なる導管です。あなたは窓と電話のセットとして家を設計しておらず、そこから床の計画を見つけようとします。あなたはその家が何をし、どのように住んでいるのかで始まります。
だから、これは簡単です:
一部のviewmodelsがAAViewModel
性質を持っています。これらのビューモデルには、あらゆる種類のシンプルまたは複雑なビューが存在する場合があります。ビューがユーザーにビューモデルのAAViewModel
のものを編集させたい場合は、AAView
がビューモデルのAAViewModel
に適切にバインドされています。 MainViewModel
とDialogViewModel
はどちらも、誰かが自分のVMのAAViewModel
のものを編集できるようにしたい、非常に複雑なインタラクティブなビューです。
MainViewModel
がDialogViewModel
の親であるか、単にモーダルダイアログに入れてDialogViewModel
の一時的なインスタンスを作成した場合は、その後、MainViewModel
は、ダイアログを表示し、それをどうするかを決定するdialogVM.AAVM.CData.IsDirty
を見て必要があります。または、dialogVM.AAVM
に新しいCDataClass
インスタンスを表示してから(おそらくそれ自身のインスタンスのクローン)、ShowModel()
がtrue
を返した場合は、dialogVM.AAVM.CData
で何かを行います。
ポイントは、あなたのビューモデルがすべてを駆動すると、お互いに通信するのが比較的簡単になるということです。親子は簡単です:親は子どもに物を与え、子どもが何をもたらすのかを見ます。ビューモデルは、別のビューモデルのPropertyChanged
イベントをサブスクライブできます。親ビューモデルはその子を監視することができます。子供に何かが起こると、親は兄弟を更新するかどうかを決定することができます。一般的に、子供は親について何も知ってはいけません。異種のコンテキストで子ビューモデルを再利用する方がずっと簡単です。保護者は、その情報をどうするかを決める必要があります。
すべてのAAViewModelは、誰かが彼にCDataClass
のコピーを渡したことを知っています。彼はそれに応じて彼の公共財産を更新する。それから、他の誰か(おそらくAAView
だが彼は知らない)は彼の特性を設定することによって彼にいくつかの変更を渡す。それに応じてCDataClass
インスタンスを更新します。しばらくして、彼に知られていない、1つのビューモデルまたは別のものが来て、それを見て、CDataClass
を見てください。
ビューとビューモデル間の通信はバインディングを介して行われます。
UPDATE
それはあなたのビューでのviewmodelsを作成していることが判明し、その結果として、あなたは親が彼らに取得することができますか見当がつかない。そして、あなたは、なぜそうした方法で子ビューのビューモデルを作成するのが良い考えではないかを知っています。
は、ここでは、私は上記のviewmodel中心の設計で子ビュー/のviewmodels行う方法は次のとおりです。
まず、ビュー内の子のviewmodelsを作成するためにやっているものは何でも取り除きます。
次に、子ビューモデルタイプのDataTemplate
を作成します。これはApp.xamlのリソースにマージされたリソースディクショナリに入れなければなりませんが、怠け者になって2つの異なるビューのうちResources
に貼り付けるだけで、あなたを殺しません。
あなたの名前空間宣言がどのようなものかわかりません。ビューはxmlns:view="..."
と呼ばれ、ビューモデルはxmlns:vm="..."
という名前であると仮定します。今
<DataTemplate DataType="{x:Type vm:AAAViewModel}">
<view:AAAView />
</DataTemplate>
、あなたは(そしてそれはそれらのほとんどです)ContentControl
から継承する任意のコントロールのContentProperty
にAAAViewModel
を割り当てることができ、およびテンプレートがインスタンス化されます。つまり、XAMLはAAAView
を作成し、そのインスタンスAAAViewModel
を、作成したばかりのAAAView
のDataContext
プロパティに割り当てます。
次に、子供AAAViewModel
を作成してから、それをUIに表示します。
public class DialogViewModel
{
// You can create this in DialogViewModel's constructor if you need to
// give it parameters that won't be known until then.
private AAAViewModel _aaavm = new AAAViewModel();
public AAAViewModel AAAVM
{
get { return _aaavm; }
protected set {
_aaavm = value;
OnPropertyChanged(nameof(AAAVM));
}
}
そして今、我々はDialogView
でAAAVM
を表示することができます。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl
Content="{Binding AAAVM}"
Grid.Row="0"
/>
<StackPanel Orientation="Vertical" Grid.Row="1">
<!-- Other stuff -->
</StackPanel>
</Grid>
今MainViewModel
がDialogViewModel
と連絡を取るんか?ダイアログの場合は、寿命が限られているため、独自のビューモデルを作成することは実際には大したことではありません。どちらにしてもかまいません。私は、以下の2番目の例のように、自分自身を作成することに向かって傾いています。
全く同じではありませんが、近いです。最初に、もう一度、ダイアログが独自のビューモデルを作成する場所で何をしているのかを取り除きます。
MainViewModel。cs
public CDataClass CDC { /* you know the drill */ }
public void ShowDialog()
{
var dvm = new DialogViewModel();
// Maybe this isn't what you want; I don't know what CDataClass does.
// But I'm assuming it has a copy constructor.
dvm.AAAVM.CDC = new CDataClass(this.CDC);
if (DialogView.ShowDialog(dvm).GetValueOrDefault())
{
CDC = dvm.CDC;
}
}
この次はviewmodelではなく、viewcodebehindです。
DialogView.xaml.cs
今
public static bool? ShowDialog(DialogViewModel dvm)
{
var vw = new DialogView() { DataContext = dvm };
return vw.ShowDialog();
}
、あなたダイアログは、独自のviewmodelの作成を続行しましょう可能性があり、
DialogView.xaml.cs
public static bool? ShowDialog(CDataClass cdc)
{
var dlg = new DialogView();
dlg.ViewModel.AAAVVM.CDC = cdc;
return dlg.ShowDialog();
}
そして親が相互作用することもできます。このような
public DialogViewModel ViewModel => (DialogViewModel)DataContext;
そして、ShowDialogメソッド:その場合、あなたはそれをこのような公共の財産を与えるだろうその代わりに、このような:
MainViewModel.cs
public void ShowDialog()
{
var cdcClone = new CDataClass(this.CDC);
if (DialogView.ShowDialog(cdcClone).GetValueOrDefault())
{
CDC = cdcClone;
}
}
素敵できちんとしています。
このダイアログがモーダルでない場合は、ダイアログviewmodelをMainViewModel
のプライベートメンバーにして、ダイアログのビューを維持するために、ダイアログビューモデルのイベントにサブスクライブするMainViewModel
を持っています。ユーザーがダイアログのコピーCDataClass
を更新するたびに、ダイアログでDataClassUpdated
が呼び出され、MainViewModel
には_dialogViewModel.AAAVM.CDC
でスニッファするそのイベントのハンドラがあり、その処理方法が決まります。必要に応じてサンプルコードを入手することができます。
これで、親/子ビューモデルに関してすべてを構築し、必要に応じてビューにそれらを埋め込むことができます。
CDataClassのデータが2つのビューの間で異なる場合、それらは基本的に別々のインスタンスですか? – Steve
http://stackoverflow.com/q/3801681/2470362 –