WPF CommandParameter绑定和canExecute

时间:2009-11-17 13:15:05

标签: c# wpf delegatecommand

我有一个treeView项目的模板:

<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>

作为DataContext,我有一个ID为非空字段的linq实体。

问题是:如果我使用CanExecutedMethod使用DelegateCommand'Add':

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

仅调用一次,参数为null(而textBlock显示正确的ID值)。在调用ID属性之前调用CanExecute(使用调试器检查)。似乎在绑定到实际参数之前,wpf正在调用canExecute并忘记它。绑定完成并加载正确的值后,它不会再次调用CanExecute。

作为一种解决方法,我可以使用只执行委托的命令:

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

使用正确的ID值调用AddExecute并且工作正常。但我仍然想使用CanExecute功能。有什么想法吗?

3 个答案:

答案 0 :(得分:4)

在这种情况下,最好在用作Command参数的属性上调用RaiseCanExecuteChanged()。在您的情况下,它将是您的ViewModel中的ID属性(或者您正在使用的任何DataContext)。

这将是这样的:

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

效果将与您的解决方案相同,但它会使Command逻辑远离代码隐藏。

答案 1 :(得分:2)

您可以尝试使用CommandManager.InvalidateRequerySuggested强制更新。

答案 2 :(得分:1)

我将参数用作object,然后将其强制转换回int

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

并添加方法

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

    //or simply

    int id2 = (int)parameter;

    //...
    //  do your stuff
    //...
}
相关问题