使用ICommand删除后,WPF ListBox选择下一个项目

时间:2015-05-19 11:41:22

标签: wpf xaml mvvm datagrid listbox

这个问题像this question一样出现了同样的问题,但它涉及到我遇到的另一个问题,因为我使用了绑定。

我添加了一个按钮,用于删除ListBox中当前选定的项目(以及出现同一问题的DataGrid的一个项目)。执行此操作的代码通过ICommand - 对象和Button.Command属性绑定到按钮:

<Button Command="{Binding DeleteRowCommand}"
        CommandParameter="{Binding ElementName=MyListBox, Path=SelectedItem}" />

然而,这意味着点击操作直接汇集到ViewModel中,ViewModel当然不知道视图的ListBox,因此它无法通知视图或更新任何选择。

在viewmodel 视图中触发代码隐藏的正确方法是什么?

也许我可以使用命令属性和Handles语句,但我不确定这是否可行。

2 个答案:

答案 0 :(得分:1)

这就是我要做的事。

在ViewModel中创建一个属性,该属性将保存SelectedItem。

private YourTypeHere _SelectedThing;

public YourTypeHere SelectedThing 
{
   get { return _SelectedThing; }
   set 
   { 
      _SelectedThing = value;

      //Call INotifyPropertyChanged stuff
    }
}

现在,将List的SelectedItem绑定到此属性:

<ListBox SelectedItem="{Binding SelectedThing}" ... />

执行这些操作意味着您的SelectedThing现在是ViewModel的责任,当您调用Delete命令时,您只需将SelectedThing属性更新为列表中的最后一项并且您的ListBox将自动更新。

答案 1 :(得分:0)

XAML:

<ListBox DataContext="{Binding Path=Category, Mode=OneTime}"
         ItemsSource="{Binding Path=Fields}"
         SelectedItem="{Binding Path=SelectedItem, Mode=OneWay}"
         SelectedIndex="{Binding Path=SelectedIndex}" />

CategoryViewModel中的代码,来自数据上下文的Category对象的类:

Public ReadOnly Property Fields As ObservableCollection(Of FieldViewModel)
  Get
    Return m_Fields
  End Get
End Property
Private ReadOnly m_Fields As New ObservableCollection(Of FieldViewModel)

Public Property SelectedIndex As Integer
  Get
    Return m_SelectedIndex
  End Get
  Set(value As Integer)
    m_SelectedIndex = value
    ValidateSelectedIndex()
    RaisePropertyChanged("SelectedIndex")
    RaisePropertyChanged("SelectedItem")
  End Set
End Property
Private m_SelectedIndex As Integer = -1

Public ReadOnly Property SelectedItem As FieldViewModel
  Get
    Return If(m_SelectedIndex = -1, Nothing, m_Fields.Item(m_SelectedIndex))
  End Get
End Property

Private Sub ValidateSelectedIndex()
  Dim count = m_Fields.Count
  Dim newIndex As Integer = m_SelectedIndex

  If count = 0 Then
    ' No Items => no selections
    newIndex = -1
  ElseIf count <= m_SelectedIndex Then
    ' Index > max index => correction
    newIndex = count - 1
  ElseIf m_SelectedIndex < 0 Then
    ' Index < min index => correction
    newIndex = 0
  End If

  m_SelectedIndex = newIndex
  RaisePropertyChanged("SelectedIndex")
  RaisePropertyChanged("SelectedItem")
End Sub

Public Sub New(model As Category)
  ' [...] Initialising of the view model,
  ' especially the m_Fields collection

  ' Auto update of SelectedIndex after modification
  AddHandler m_Fields.CollectionChanged, Sub() ValidateSelectedIndex()
  ' Set the SelectedIndex to 0 if there are items
  ' or -1 if there are none
  ValidateSelectedIndex()
End Sub

现在,每当您从m_Fields集合中删除某个项目时,SelectedItem都会更改为下一个项目,如果删除了最后一个项目,则会更改为上一个项目,或Nothing如果最后剩下的项目被删除了。