当上下文菜单打开时,ListBox选定的项目未更新

时间:2014-02-21 19:20:42

标签: c# wpf mvvm listbox contextmenu

我的WPF应用程序有一个包含大量项目的ListBox。当用户用鼠标右键单击一个项目打开上下文菜单时,我需要评估当前选择的项目以构建菜单项标题,告诉用户该命令会发生什么。

此命令将对项目设置过滤器,并应提前指示生成的过滤器,该过滤器基于所选项目的数据。

由于我不知道有什么方法可以通过MVVM将ListBox的选定项目放入视图模型中,所以我用后面的代码完成了它。 SelectionChanged事件处理程序将所选项发送到视图模型。

不幸的是,当用户点击足够快时,此选定项目列表已过时。我经常看到以前的选择,而不是当前的选择。只有当我按住鼠标右键足够长时,选择才是最新的。

以下是我的测试应用的截图(下方):

enter image description here

问:如何可靠地获取上下文菜单标题的当前选择?

我做了一个非常简单的测试用例,因此您可以重现该问题。转换器具有短暂的延迟来模拟活动。我的真实转换器没有这种延迟,但由于视图更复杂,加载UI也需要很短的时间,这具有相同的效果。

以下是代码:https://drive.google.com/file/d/0B8CN0ghdY1SdTW9Ka1lHc1dIUFk/edit

2 个答案:

答案 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时,您需要触发属性更改。