Correct MVVM pattern WPF Command implementation

I'm trying to implement commands following the MVVM pattern, but I'm stuck with this particular scenario.

In the XAML I've binded a command to a button inside a column:

<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>

In my ViewModel I've declared a 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

I initialized the command inside the ViewModel's constructor:

DeleteRowCommand = New DelegateCommand(Of Object)(AddressOf DeleteRowCommandExecute)

And finally I execute the command:

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

Everything works as expected, but as far as I know the ViewModel should know nothing about the View, therefore deleting the row inside the ViewModel is incorrect.

What is the best way to do this following MVVM pattern?

UPDATE: Deleting the item from the ObservableCollection binded to the ItemsSource of the Grid works perfectly, but what if I need to remove an UI element like a StackPanel from a Grid which don't have an ItemsSource?

<Grid>
    <StackPanel>
        <Button Content="Delete" Height="25" Width="100" Command="{Binding DeleteItemCommand}" 
                CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=StackPanel}}" />
    </StackPanel>
</Grid>

UPDATE2: My goal is to have a container to which I can add items (UserControl) dynamically and where I'm able to change the order of this items at runtime. At the moment I'm using a Grid as a container to which I add a new RowDefinition everytime I insert a new item. I the use Grid.Row property to keep track and change the items' order. This way I need to do all the delete operations in the code behind since I have to manually remove the RowDefinition from the Grid.


Deleting the item from the ObservableCollection binded to the ItemsSource of the Grid works perfectly, but what if I need to remove an UI element like a StackPanel from a Grid which don't have an ItemsSource?

Since this code is purely view-related, it should be implemented in the code-behind of the view (or in the control itself where it applies). The view model shouldn't know anything about any UI elements so it makes no sense to implement a command that removes these elements.

MVVM is not about eliminating view-related code from the views. It is about separation of concerns. So keep everything that is related to UIElements and Panels in your view.

链接地址: http://www.djcxy.com/p/56192.html

上一篇: WPF路由命令和ShowDialog窗口

下一篇: 正确的MVVM模式WPF命令实现