首次尝试在业务线项目上实现 MVVM 模式。我遇到了一些问题,我认为像这样的问题有更简单的答案:
原型窗口是项目列表的基本主从视图。(一个 Person 对象列表)。该视图包含主列表的 Infragistics xamDataGrid。当项目在网格中被选中时,您可以在下面的详细信息面板中编辑详细信息,并且当您在详细信息面板中的字段上按标签时,更新会在网格数据中“实时”显示。唯一的问题是我不想要“presto”,我想要“等到我按下‘应用更改’按钮”。
我希望避免创建一个单独的列表实例,以将主列表与我在详细信息面板中添加/删除/修改的工作组分开。
我走过的路:
我覆盖了网格字段中的 CellValuePresenter 样式,因此我可以将绑定设置为“OneWay”。这会阻止实时更新。
<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 将包装相同的业务对象,但 ReadOnly 版本不会发布更改。这将使 VM 控制视图何时更新。