我的WPF应用程序有一个包含大量项目的ListBox。当用户用鼠标右键单击一个项目打开上下文菜单时,我需要评估当前选择的项目以构建菜单项标题,告诉用户该命令会发生什么。
此命令将对项目设置过滤器,并应提前指示生成的过滤器,该过滤器基于所选项目的数据。
由于我不知道有什么方法可以通过MVVM将ListBox的选定项目放入视图模型中,所以我用后面的代码完成了它。 SelectionChanged事件处理程序将所选项发送到视图模型。
不幸的是,当用户点击足够快时,此选定项目列表已过时。我经常看到以前的选择,而不是当前的选择。只有当我按住鼠标右键足够长时,选择才是最新的。
以下是我的测试应用的截图(下方):
问:如何可靠地获取上下文菜单标题的当前选择?
我做了一个非常简单的测试用例,因此您可以重现该问题。转换器具有短暂的延迟来模拟活动。我的真实转换器没有这种延迟,但由于视图更复杂,加载UI也需要很短的时间,这具有相同的效果。
以下是代码:https://drive.google.com/file/d/0B8CN0ghdY1SdTW9Ka1lHc1dIUFk/edit
答案 0 :(得分:1)
将ViewModel更新为此
internal class MainViewModel : INotifyPropertyChanged
{
private List<string> _selectedItems;
public MainViewModel()
{
MenuCommand = new MenuCommand();
StringItems = new List<string>();
StringItems.Add("Hello");
StringItems.Add("world");
StringItems.Add("of");
StringItems.Add("mysterious");
StringItems.Add("WPF");
}
public List<string> StringItems { get; set; }
public MenuCommand MenuCommand { get; private set; }
public string MenuCommandTitle
{
get { return "Selected items: " + SelectedItems.Aggregate((a, b) => a + ", " + b); }
}
public List<string> SelectedItems
{
get { return _selectedItems; }
set
{
_selectedItems = value;
OnPropertyChanged("MenuCommandTitle");
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
您想要更新ContextMenu的绑定,以通知UI新值。
OnPropertyChanged("MenuCommandTitle");
答案 1 :(得分:0)
您的MainViewModel似乎未实现INotifyPropertyChanged,因此您的MenuCommandTitle属性并不总是更新。当您在代码隐藏中更新SelectedItems
时,您需要触发属性更改。