首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RelayCommand未触发CanExecute

RelayCommand未触发CanExecute
EN

Stack Overflow用户
提问于 2012-02-18 19:03:06
回答 2查看 2K关注 0票数 0

我正在尝试创建一个绑定到按钮的命令,该命令依赖于视图模型的层次结构来表示wp7应用程序中的枢轴和枢轴标题。它是这样的(我将尽可能省略更多的样板代码):

代码语言:javascript
复制
    public RelayCommand RefreshCommand
    {
        get
        {
            return _refreshCommand;
        }

        set
        {
            if (_refreshCommand == value)
            {
                return;
            }

            var oldValue = _refreshCommand;
            _refreshCommand = value;

            // Update bindings, no broadcast
            RaisePropertyChanged(RefreshCommandPropertyName);
        }
    }


    public RelayCommand<RoutedEventArgs> LoadedCommand
    {
        get
        {
            Action<RoutedEventArgs> getCurrentViewmodel = (args) =>
            {
                CurrentViewModel = SearchByLocationViewModel; // maybe something better...
                RefreshCommand = CurrentViewModel.RefreshResultsCommand;
                RefreshCommand.RaiseCanExecuteChanged();
            };
            return new RelayCommand<RoutedEventArgs>(getCurrentViewmodel);
        }
    }

    public RelayCommand<SelectionChangedEventArgs> PivotItemChangedCommand
    {
        get
        {
            Action<SelectionChangedEventArgs> pivotChanged = (args) =>
            {
                if (args != null)
                {
                    // update current viewmodel
                    CurrentViewModel = ((Microsoft.Phone.Controls.PivotItem) args.AddedItems[0]).DataContext as ISearchViewModelBase;
                    RefreshCommand = CurrentViewModel.RefreshResultsCommand;
                }
            };
            return new RelayCommand<SelectionChangedEventArgs>(pivotChanged);
        }
    }

因此,每次加载父视图模型时,我都会将父视图模型的RefreshCommand属性设置为子命令,当选定的透视项发生更改时,我也会这样做。

Xaml

代码语言:javascript
复制
<Button Command="{Binding RefreshCommand}" />

子视图模型

代码语言:javascript
复制
public Func<bool> CanRefresh
{
    get { return () => !IsLoading; }
}

private RelayCommand refreshResultsCommand;

public RelayCommand RefreshResultsCommand
{
    get
    {
        Action doRefresh = () =>
        {
            SearchResults.Clear();
            this._pageNumber = 0;
            AddItems();
        };
        return refreshResultsCommand = refreshResultsCommand ?? new RelayCommand(doRefresh, CanRefresh);
    }
}

实际情况是,CanRefresh永远不会被调用。这些命令可以很好地工作,这取决于它调用的pivotitem是一个AddItems (这是一个在每个子视图模型中以不同方式实现的虚拟方法)还是另一个,但它就像CanExecute从未被引发过一样。谢谢!

EN

回答 2

Stack Overflow用户

发布于 2012-02-19 01:41:44

我怀疑CanExecute方法永远不会被调用,因为RelayCommandCanExecuteChanged事件永远不会在视图层当前绑定到的视图模型对象上触发。由于您是在大多数属性访问上创建命令,因此有很多命令,很可能是在尚未绑定到视图层的命令上或在不再绑定到的命令上触发事件。

我从未见过任何人在每次调用属性getter时创建新命令。您是否可以尝试在构造函数中创建一次命令,而不是在每次访问属性时创建命令,并查看是否可以修复问题?

票数 1
EN

Stack Overflow用户

发布于 2012-02-19 01:15:49

那么,每次调用LoadedCommandPivotChangedComman属性时,您都会创建一个新的中继命令。由于SL/WPF非常频繁地调用这些属性,因此您必须确保不会在每次调用属性时都创建命令。实际上,您的RefreshResultsCommand实现了正确的模式。

确保正确实现属性/命令的最好方法是使用Laurent's MVVM snippets。将它们下载到您的snippet目录并使用它们。除了总是产生相同的样板代码,从而提高质量,他们也加速了相当多!

您也可以使用use the installer来安装这些代码片段。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9340591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档