谓词不会正确验证参数

时间:2016-04-12 06:04:25

标签: c# wpf mvvm icommand

这是我的其他主题的另一个问题: MVVM Navigating through different Views,我已经想到,到目前为止没有人解决的问题(其他线程)。这个问题与我的命令谓词(CanExecute Method)有关。

public RelayCommand ChangePageCommand {
        get {
            return new RelayCommand(p => ChangeViewModel((BaseViewModel)p), x => x is BaseViewModel);
        }
    }

    public RelayCommand TestChangePageCommand {
        get {
            return new RelayCommand(p => MessageBox.Show((p is BaseViewModel).ToString()), x => true);
        }
    }

我已经创建了某种测试方法来确定实际问题的位置:

MessageBox.Show((p is BaseViewModel).ToString()) 
来自TestChangePageCommand的

显示一个带有“true”的Dialogbox,但来自ChangePageCommand的谓词

x => x is BaseViewModel

总是返回“false”(如果实现了TestChangePageCommand也会返回谓词)

任何人都可以告诉我为什么我的应用程序会像这样?

更新1:

输出窗口显示:

无法使用绑定检索值,并且不存在有效的回退值;使用默认值。 BindingExpression:路径=首页;的DataItem = NULL; target元素是'Button'(Name =''); target属性是'CommandParameter'(类型'Object')

更新2:

我检查了ViewModel,发现HomePage在设置为CurrentPageViewModel时不为null。是否有可能在创建ViewModel并且尚未定义HomePage时执行CanExecute方法?我怎么能解决这个问题?

UserAdministrationViewModel which contains the HomeViewModel (as HomePage)

2 个答案:

答案 0 :(得分:1)

正如丹尼斯在评论中提到的那样,你应该尝试扼杀你的命令。请尝试接下来的事情,将断点放在谓词行,看看你得到了什么:

"\\"

尝试更改下一个方法:

    ICommand _command;
    public RelayCommand ChangePageCommand
    {
        get
        {
            return _command ?? (_command = new RelayCommand(p => ChangeViewModel((BaseViewModel) p), x =>
            {
                x is BaseViewModel;
            }));
        }
    }

更新#2 - 这是您的代码

    public void ChangeViewModel(BaseViewModel viewModel)
    {
        //You should implement clone in your base view model
        CurrentPageViewModel = viewModel.Clone();
    }

我认为您应该将UpdateSourseTrigger = PropertyChanged添加到Button CommandParameter定义中。据我所知,只有在没有任何类型窗口的祖先时,HomePage才能为空。只有在两个DataTemplates(在您的情况下)之间导航时才会发生这种情况。试着用这种方法思考。

此致

答案 1 :(得分:0)

最后给我的UserControl一个Name并沿着ElementName重定向CommandProperty就可以了:

<Button Content="{Binding Name}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
        CommandParameter="{Binding DataContext.HomePage, ElementName=Test}"/>

有人可以解释为什么Binding to the Name(位于同一个Base类中)没有ElementName /提供额外的信息但主页没有?