我正在使用Prism.MVVM的WPF视图,它允许我们的用户编辑记录。 最初要编辑的记录是通过ComboBox选择的。
<ComboBox IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Records}"
SelectedItem="{Binding SelectedRecord}"/>
这很有用,但是用户想要一种更有效的方法来查找哪些记录包含需要更新的字段,因此我们添加了一个只读的DataGrid,他们可以对它们进行排序并直观地发现他们感兴趣的记录。接下来他们想要选择记录以编辑网格(但保留组合框)。这是出问题的地方。
理想情况下,我们正在寻找的行为是:
如果用户从组合框中选择一条记录:
如果用户在网格中选择记录
在DataGrid的SelectionChanged事件上触发命令
<DataGrid x:Name="TheDataGrid"
ItemsSource="{Binding Source={StaticResource GridRecords}}"
SelectedItem="DataContext.SelectedRecord, ElementName=LayoutRoot, Mode=OneWay}">
...
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction CommandParameter="{Binding SelectedItem, ElementName=TheDataGrid}"
Command="{Binding DataContext.SelectRecordFromGridCommand, ElementName=LayoutRoot}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
DelegateCommand:
Public ReadOnly Property SelectRecordFromGridCommand As DelegateCommand(Of TheRecordType) = new DelegateCommand(Of TheRecordType)(Sub(r) SelectedRecord = r)
尝试使用SelectedItem
绑定模式的各种选项。
如果删除了DataGrid SelectedItem
绑定,我们得到1,2,4,5,6和7.但是从组合框中选择记录将不会显示在网格中选择的记录。
如果DataGrid SelectedItem
绑定设置为OneWay
,则通过组合框选择记录会中断:设置SelectedRecord
会触发DataGrid中的SelectionChanged事件,该事件使用之前的值事件并有效地将一切恢复到原始值。
可以通过在ViewModel中的属性集上引入一个sentinal来解决这个问题
Private _selectedRecord As TheRecordType
Private _enableRecordSelection As Boolean = true
Public Property SelectedRecord As TheRecordType
Get
Return _selectedRecord
End Get
Set(value As TheRecordType)
If _enableRecordSelection
_enableRecordSelection = false
SetProperty(_selectedRecord , value)
_enableRecordSelection = true
End If
End Set
End Property
这实际上是有效的,我们在写这个问题时提出了它,但感觉非常hacky。我的直觉告诉我必须有一个更好的方式,所以我还在问:
是否有干净的(最好是仅限xaml)方式进行设置?
具有TwoWay绑定的DataGrid的直接xaml配置
<DataGrid x:Name="TheDataGrid"
ItemsSource="{Binding Source={StaticResource GridRecords}}"
SelectedItem="DataContext.SelectedRecord, ElementName=LayoutRoot, Mode=TwoWay}"/>
有了这个,我们满足要求1到6;但是,当通过网格选择记录时,前一条记录始终会突出显示而不是当前记录。
DataGrid.InputBindings
<DataGrid.InputBindings>
<MouseBinding Gesture="LeftClick"
CommandParameter="{Binding SelectedItem, ElementName=TheDataGrid}"
Command="{Binding DataContext.SelectRecordFromGridCommand, ElementName=LayoutRoot}"/>
</DataGrid.InputBindings>
没有SelectedItem
绑定,这与InteractionTrigger
上的无绑定SelectionChanged
的行为类似,但它要求用户执行多个鼠标操作。第一次单击选择网格中的行(实际的粗体蓝色选择)第二次单击会触发命令。
在OneWay
上绑定SelectedItem
时,此行为与直接xaml配置类似,但需要多次点击。
再次重申这个问题: 有没有更简洁的方法来完成7个要求而不是求助于属性设置器上的sentinal值?