6

我有一个 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 我有 linq 实体 ID 不是空字段。

问题是:如果我将 DelegateCommand 'Add' 与 CanExecutedMethod 一起使用:

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

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

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

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

AddExecute 使用正确的 ID 值调用,并且运行良好。但我仍然想使用 CanExecute 功能。有任何想法吗?

4

3 回答 3

4

在这种情况下,最好在用作命令参数的属性上调用 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();
    }
}

效果将与您的解决方案相同,但它将命令逻辑排除在代码隐藏之外。

于 2011-10-14T09:50:14.730 回答
2

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

于 2009-11-17T13:21:33.800 回答
1

我使用参数 asobject然后将其转换回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
    //...
}
于 2015-01-04T11:48:37.163 回答