我有一个 MVVM 绑定的 ComboBox
<ComboBox x:Name="CBRootPathComboBox"
ItemsSource="{Binding RootPathComboBoxItems, Mode=OneTime}"
DisplayMemberPath="DisplayName"
SelectedItem="{Binding SelectedRootPathComboBoxItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction
Command="{Binding RootPathComboBoxItemSelectionChangedCommand}"
CommandParameter="{Binding ElementName=CBRootPathComboBox, Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
Interaction
来自 Microsoft.Xaml.Behaviors.Wpf
nuget。
在
SelectionChanged
上,我期望看到 ICommand
以及列表中当前选定的项目。
在 ViewModel 中,我在代码中的某个位置设置了
SelectedItem
。
我使用 ViewModel 属性在 ViewModel 中将其从“Item2”设置为“Item1”。
调用链如下:
1. set the property to "Item1"
2. Raise INotifyPropertyChanged.PropertyChanged event
3. .Net internals calls property getter, it returns "Item1"
4. ICommand call contains "Item2" in parameter. Expected: "Item1"
ViewModel 属性:
private RootPathItem _selectedRootPathComboBoxItem;
public RootPathItem SelectedRootPathComboBoxItem
{
get
{
Debug.WriteLine($"getting {_selectedRootPathComboBoxItem?.DisplayName ?? "null"}");
return _selectedRootPathComboBoxItem;
}
set
{
Debug.WriteLine($"setting {value?.DisplayName ?? "null"}");
if (_selectedRootPathComboBoxItem != value)
{
Debug.WriteLine($"overwriting {_selectedRootPathComboBoxItem?.DisplayName ?? "null"}");
_selectedRootPathComboBoxItem = value;
this.OnPropertyChanged();
}
}
}
几种解决方案。
private RootPathItem _selectedRootPathComboBoxItem;
public RootPathItem SelectedRootPathComboBoxItem
{
get
{
Debug.WriteLine($"getting {_selectedRootPathComboBoxItem?.DisplayName ?? "null"}");
return _selectedRootPathComboBoxItem;
}
set
{
Debug.WriteLine($"setting {value?.DisplayName ?? "null"}");
if (_selectedRootPathComboBoxItem != value)
{
Debug.WriteLine($"overwriting {_selectedRootPathComboBoxItem?.DisplayName ?? "null"}");
_selectedRootPathComboBoxItem = value;
this.OnPropertyChanged();
RootPathComboBoxItemSelectionChangedExecute(value);
}
}
}
<ComboBox x:Name="CBRootPathComboBox"
ItemsSource="{Binding RootPathComboBoxItems, Mode=OneTime}"
DisplayMemberPath="DisplayName"
SelectedItem="{Binding SelectedRootPathComboBoxItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction
Command="{Binding RootPathComboBoxItemSelectionChangedCommand}"
EventArgsParameterPath="AddedItems[0]" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
i:Interaction.Behaviors
而不是 i:Interaction.Triggers
。代码中稍微复杂一些的是 InvokeCommandAction
与 Behavior
。