WPF CommandParameter binding and canExecute

半城伤御伤魂 提交于 2020-01-02 03:47:05

问题


I have a template for treeView item:

<HierarchicalDataTemplate x:Key="RatesTemplate">
    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=ID}"/>
                        <Button CommandParameter="{Binding Path=ID}" 
                                Command="{Binding ElementName=CalcEditView, Path=DataContext.Add}">Add</Button>                            
    </StackPanel>
</HierarchicalDataTemplate>

As a DataContext I have linq entity with ID not null field.

The problem is: if I use DelegateCommand 'Add' with CanExecutedMethod:

AddRate = new DelegateCommand<int?>(AddExecute,AddCanExecute);

its called only once and parameter is null (while textBlock shows proper ID value). CanExecute is called before ID property is called (checked with debugger). Seems like before binding to actual parameter wpf is invoking canExecute and forgets about it. Once binding finished and proper value loaded it doesn't call CanExecute again.

As a workaround I can use command with only execute delegate:

Add = new DelegateCommand<int?>(AddExecute);

AddExecute is invoked with correct ID value and is working perfectly. But I still want to use CanExecute functionality. Any ideas?


回答1:


In this scenario, it's better to call the RaiseCanExecuteChanged() on the property used as a parameter for the Command. In your case, it would be the ID property in your ViewModel (Or whichever DataContext you're using).

It would be something like this:

private int? _id;
public int? ID
{
    get { return _id; }
    set
    {
        _id = value;
        DelegateCommand<int?> command = ((SomeClass)CalcEditView.DataContext).Add;
        command.RaiseCanExecuteChanged();
    }
}

The effect will be the same as your solution, but it keeps the Command logic out of code-behind.




回答2:


You can try to use CommandManager.InvalidateRequerySuggested to force an update.




回答3:


I use parameter as object and then cast it back to int.

Add = new DelegateCommand<object>(add, canAdd);

and in add method

void add(object parameter){
    int id = Convert.ToInt32(parameter);

    //or simply

    int id2 = (int)parameter;

    //...
    //  do your stuff
    //...
}


来源:https://stackoverflow.com/questions/1748792/wpf-commandparameter-binding-and-canexecute

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