基幹業務プロジェクトに MVVM パターンを実装する最初の試み。次のような簡単な答えがあると思われる質問に出くわしています。
プロトタイプ ウィンドウは、アイテム リストの基本的なマスター詳細ビューです。(Person オブジェクトのリスト)。ビューには、マスター リストの Infragistics xamDataGrid が含まれています。グリッドでアイテムが選択されると、下の詳細パネルで詳細を編集できます。詳細パネルのフィールドをタブで移動すると、更新がグリッド データに「リアルタイム」で表示されます。唯一のことは、「プレスト」が必要ないことです。「[変更を適用] ボタンを押すまで待ちたい」ということです。
詳細パネルで追加/削除/変更しているアイテムの作業セットからマスターリストを分離するために、リストの別のインスタンスを作成しないようにしたいと考えていました。
私が行った道:
バインディングを「OneWay」に設定できるように、グリッド フィールドの CellValuePresenter スタイルをオーバーライドしました。これにより、リアルタイムの更新が妨げられます。
<ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}">
<ControlTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="{Binding Path=DataItem.NameUIProperty.IsDirty, Converter={StaticResource BooleanBrushConverter}}" />
<Setter Property="IsEnabled" Value="{Binding Path=DataItem.NameUIProperty.IsEditable}" />
</Style>
</ControlTemplate.Resources>
<ContentControl>
<TextBlock Text="{Binding Path=DataItem.Name, Mode=OneTime}" />
</ContentControl>
</ControlTemplate>
次に、「ApplyUpdates」コマンド (RelayCommand) を PersonListViewModel に追加します。これにより、「PERSON _ITEM_
UPDATED」メッセージが発生します。MVVM Foundation Messenger および RelayCommand クラスの VB ポートを使用しています。
#Region "ApplyUpdates Command"
Private mApplyUpdatesCommand As New RelayCommand(AddressOf ApplyUpdates)
Public ReadOnly Property ApplyUpdatesCommand() As ICommand
Get
Return mApplyUpdatesCommand
End Get
End Property
Private Sub ApplyUpdates()
'the changes are already in the object in the list so we don't have to do anything here except fire off the Applied message
Messages.AppMessenger.NotifyColleagues(Messages.PERSON_ITEM_UPDATED)
End Sub
#End Region
PersonView は PERSON _ITEM_
UPDATED メッセージを登録し、メッセージの受信時にグリッドを再バインドします。
'In Loaded Event
'register for window messages we care about
Messages.AppMessenger.Register(Messages.PERSON_ITEM_UPDATED, AddressOf OnPersonItemUpdated)
'EventHandler
Private Sub OnPersonItemUpdated()
PersonGrid.DataSource = Nothing
PersonGrid.DataSource = mViewModel.List
End Sub
それで、それはうまくいきますが、それは間違ったにおいがします. ビューにはあまりにも多くのロジックが含まれているようで、ViewModel は UI の状態を指示していません。ビューはそうです。
私は何が欠けていますか?ビューへの変更の公開を遅らせるために ViewModel を取得するには、どのような方法を使用しますか?
更新: 現在、グリッド用のカスタム ViewModel (読み取り専用、Propertychanged 通知なし) と詳細領域用の編集可能な ViewModel を作成する道をたどっています。両方の VM が同じビジネス オブジェクトをラップしますが、読み取り専用バージョンは変更を発行しません。これにより、ビューがいつ更新されるかを VM が制御できるようになります。