2009-11-17 70 views
6

我有一个TreeView项模板:WPF CommandParameter结合和canExecute

<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 NOT NULL字段LINQ实体。

的问题是:如果我使用DelegateCommand“添加”与CanExecutedMethod:

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

其称为只有一次,参数为空(在文本块显示正确的ID值)。在调用ID属性之前调用CanExecute(使用调试器进行检查)。看起来像绑定到实际参数之前wpf正在调用canExecute并忘记它。一旦绑定完成并载入适当的值,它不会再次调用CanExecute。

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

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

AddExecute被调用,有正确的ID值,并且可以正常使用。但我仍然想使用CanExecute功能。有任何想法吗?

回答

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(); 
    } 
} 

效果会与您的解决方案,但它一直在指挥逻辑出的代码隐藏。

1

我使用参数object,然后将其重新转换回int

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

和add方法

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

    //or simply 

    int id2 = (int)parameter; 

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