Predicate won't validate parameter correctly

家住魔仙堡 提交于 2019-12-12 03:26:57

问题


This is an additional question to my other Thread here: MVVM Navigating through different Views, I've figured out, that the problem no one solved so far (other thread). This question is related to my command's Predicate(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);
        }
    }

I've created some sort of Test Method to determine where the actual problem is located:

MessageBox.Show((p is BaseViewModel).ToString()) 

from TestChangePageCommand shows a Dialogbox with "true" but the Predicate from the ChangePageCommand

x => x is BaseViewModel

always returns "false" (also the Predicate from TestChangePageCommand does if implemented)

May anyone can tell why my App behaves like this?

Update 1:

The Output Window says:

Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=HomePage; DataItem=null; target element is 'Button' (Name=''); target property is 'CommandParameter' (type 'Object')

Update 2:

I've checked the ViewModel and found out that HomePage is NOT null when it get's set as the CurrentPageViewModel. Is it possible that the CanExecute Method gets executed when the ViewModel is created and the HomePage is not yet defined? How could I solve this?


回答1:


As Dennis mentioned above in comments you should try to cashe your command. Pleas try the next thing, put the breakpoint at the predicate line, and see what you get:

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

Try to change the next method:

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

Update #2 - Here is your code

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

I think you should add the UpdateSourseTrigger=PropertyChanged to your Button CommandParameter definition. As I can understand the HomePage can be null only in time when there is no any Ancestor of type window there. This will happened only when you navigate between two DataTemplates(in your case). Try to think in this approach.

Regards,




回答2:


In the end giving my UserControl a Name and redirect the CommandProperty along the ElementName did the trick:

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

Could anyone explain why Binding to the Name (which is located in the same Base class) works without the ElementName / giving additional Information but the HomePage doesn't?



来源:https://stackoverflow.com/questions/36564788/predicate-wont-validate-parameter-correctly

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!