由于WeakReference,我的RelayCommand没有执行吗?

时间:2014-03-17 13:19:59

标签: c# wpf mvvm

使用异步方法时,我遇到了MVVM的RelayCommand问题。

假设我连接到服务器以使用await关键字获取项目列表。在我得到结果后,我做一个Linq查询来过滤我想要显示的那些。之后,我创建了类型为MenuContextItem的ViewModel,它具有相同类型的Children。 MenuContextItem具有类型为RelayCommand的Command属性。在视图方面,我有一个Menu,它将ItemsSource属性绑定到ParentItem(它与可观察集合上的其他项封装)。

所有项目都正确显示但是创建async的项目不执行命令,我认为它与async和RelayCommand中使用的WeakReference有关,但我不知道为什么。

        var itemsSource = await Task.Run(() => GetTheItems());
        var parentItem = new MenuContextItem("Parent Item", new ObservableCollection<MenuContextItem>());

        var finalItems = itemsSource.Where((e) => SOME QUERY HERE ).ToList();
        foreach (var e in finalItems)
        {
            parentItem.Children.Add(
                new MenuContextItem(
                    e.ItemDescription,
                    new Command<object>((menu) => ItemSpecificAction(e)),
                    true
                    ));
        }

更新:经过一些更多的测试后,似乎异步调用不是问题,但我不知道可能是什么,我有相同的代码用于手动创建其他项目,它可以作为预期

编辑:添加了MenuContextItem声明

public class MenuContextItem : BindableObject
{
    #region private declarations
    private string _title;
    private Uri _icon;
    private RelayCommand<object> _command;
    private bool _isActive;
    private ObservableCollection<MenuContextoItem> _children;
    private Action<object> _action;
    #endregion

    #region initialization
    public MenuContextItem(string title, Action<object> action, bool isActive)
    {
        Title = title;
        IsActive = isActive;
        _action = action;
    }

    .... A few other constructors
    #endregion

    #region properties
    public string Title
    {
        get { return _title; }
        set
        {
            if (_title != value)
            {
                _title = value;
                RaisePropertyChanged(() => Title);
            }
        }
    }

    public Uri Icon
    {
        get { return _icon; }
        set
        {
            if (_icon != value)
            {
                _icon = value;
                RaisePropertyChanged(() => Icon);
            }
        }
    }
    public RelayCommand<object> Command
    {
        get
        {
            if (_command == null && _action != null)
                _command = new RelayCommand<object>(_action);
            return _command;
        }
        set
        {
            if (_command != value)
            {
                _command = value;
                RaisePropertyChanged(() => Command);
            }
        }
    }
    public bool IsActive
    {
        get { return _isActive; }
        set
        {
            if (_isActive != value)
            {
                _isActive = value;
                RaisePropertyChanged(() => IsActive);
            }
        }
    }
    public ObservableCollection<MenuContextItem> Children
    {
        get { return _children; }
        set
        {
            if (_children != value)
            {
                _children = value;
                RaisePropertyChanged(() => Children);
            }
        }
    }
    #endregion
}

处理不同情况的相同代码示例:

var item = new MenuContextItem("Register", null, new RelayCommand<object>((item) => Register(item)));

更新2 忽略这一点,我的测试错误发现如果我使用MenuContextItem的新实例分配var项目,它将按预期工作,但如果我在ObservableCollection.Add()方法中声明新的MenuContextItem,它会丢失命令。现在我只需要知道原因。我真的想弄清楚这一点。

var item = new MenuContextItem(
                    e.Description,
                    null,
                    new RelayCommand<object>((menu) => ItemSpecificAction(e))
                    );
parentItem.Children.Add(item);

0 个答案:

没有答案