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.
上一篇: WPF路由命令和ShowDialog窗口
下一篇: 正确的MVVM模式WPF命令实现