正确的MVVM模式WPF命令实现

时间:2017-07-03 12:40:53

标签: wpf vb.net xaml mvvm command

我试图按照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应该对View一无所知,因此删除ViewModel中的行是不正确的。

在MVVM模式之后执行此操作的最佳方法是什么?

更新 从绑定到Grid的ItemsSource的ObservableCollection中删除项目可以很好地工作,但是如果我需要从没有ItemsSource的Grid中删除像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属性来跟踪和更改项目&#39;订购。 这样我需要在后面的代码中执行所有删除操作,因为我必须从Grid中手动删除RowDefinition。

1 个答案:

答案 0 :(得分:0)

  

从绑定到Grid的ItemsSource的ObservableCollection中删除项目可以很好地工作,但是如果我需要从没有ItemsSource的Grid中删除像StackPanel这样的UI元素呢?

由于此代码纯粹是与视图相关的,因此它应该在视图的代码隐藏中实现(或者在它应用的控件本身中实现)。视图模型不应该对任何UI元素有任何了解,因此实现删除这些元素的命令是没有意义的。

MVVM不是要从视图中删除 view 相关的代码。这是关于分离关注点。因此,请在视图中保留与UIElementsPanels相关的所有内容。