正确的MVVM模式WPF命令实现
我试图按照MVVM模式实现命令,但我坚持使用这种特殊的场景。
在XAML中,我将一个命令绑定到列中的按钮:
<dxg:GridColumn FieldName="Delete" Header="" UnboundType="Object" Width="20" FixedWidth="True">
<dxg:GridColumn.EditSettings>
<dxe:ButtonEditSettings AllowDefaultButton="False">
<dxe:ButtonEditSettings.Buttons>
<dxe:ButtonInfo GlyphKind="Cancel" Command="{Binding DeleteRowCommand}" CommandParameter="{Binding ElementName=testView}" />
</dxe:ButtonEditSettings.Buttons>
</dxe:ButtonEditSettings>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
在我的ViewModel中,我声明了一个DelegateCommand:
Private m_deleteRowCommand As DelegateCommand(Of Object)
Public Property DeleteRowCommand() As DelegateCommand(Of Object)
Get
Return m_deleteRowCommand
End Get
Private Set(ByVal value As DelegateCommand(Of Object))
m_deleteRowCommand = value
End Set
End Property
我在ViewModel的构造函数中初始化了这个命令:
DeleteRowCommand = New DelegateCommand(Of Object)(AddressOf DeleteRowCommandExecute)
最后我执行命令:
Private Sub DeleteRowCommandExecute(ByVal parameter As Object)
Dim sender As TableView = parameter
Dim row = sender.DataControl.CurrentItem
Dim index = sender.FocusedRowHandle
sender.DeleteRow(index)
End Sub
一切都按预期工作,但据我所知,ViewModel应该对视图一无所知,因此删除ViewModel中的行是不正确的。
以下MVVM模式的最佳做法是什么?
更新:从绑定到网格的ItemsSource的ObservableCollection中删除项目完美地工作,但是如果我需要从没有ItemsSource的网格中移除一个像StackPanel的UI元素,该怎么办?
<Grid>
<StackPanel>
<Button Content="Delete" Height="25" Width="100" Command="{Binding DeleteItemCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=StackPanel}}" />
</StackPanel>
</Grid>
UPDATE2:我的目标是拥有一个容器,我可以在其中动态添加项目(UserControl),并且可以在运行时更改此项目的顺序。 此刻,我使用Grid作为容器,每次插入新项目时都会添加一个新的RowDefinition。 我使用Grid.Row属性来跟踪和更改项目的顺序。 这样我需要在后面的代码中执行所有删除操作,因为我必须手动从网格中删除RowDefinition。
从绑定到网格的ItemsSource的ObservableCollection中删除项目完美地工作,但是如果我需要从没有ItemsSource的网格中移除像StackPanel这样的UI元素,该怎么办?
由于此代码纯粹是与视图相关的,因此应该在视图的代码隐藏(或控制本身应用的代码隐藏)中实现。 视图模型不应该知道关于任何UI元素的任何信息,因此实施删除这些元素的命令是没有意义的。
MVVM不是要从视图中删除与视图相关的代码。 这是关于分离问题。 因此,在您的视图中保留与UIElements
和Panels
相关的所有内容。