TreeView绑定节点上的按钮CanExecute问题

时间:2016-04-14 16:12:26

标签: wpf catel

不确定这是不是我不了解WPF或关于Catel的事情,但是我有一个树视图,其中包含3个不同节点类型的数据窗口。可以将2个节点类型绑定到删除按钮。 button命令的绑定绑定到父控件的视图模型(而不是节点本身),并且传递了单击按钮的节点的命令参数。我正在提供其中一个数据模板的小片段(整个过程太大而无法进入此处):

<Grid Margin="10" x:Name="CriteriaGrid">
   <TreeView ItemsSource="{Binding Criteria}" >
     <DataTemplate DataType="{x:Type self:Leaf}">
         <Button Command="{Binding Source={x:Reference CriteriaGrid}, Path=DataContext.DeleteLeaf}" 
                 CommandParameter="{Binding}">X</Button>

     </DataTemplate>
   </TreeView>
</Grid>

ViewModel(再次只是一个小提取):

public class ManageCriteriaViewModel : ViewModelBase
{
    public ManageCriteriaViewModel()
    {
        DeleteLeaf = new Command<Leaf>(OnDeleteLeaf, CanDeleteLeaf);
    }

    private bool CanDeleteLeaf(Leaf leafNode)
    {
        return (leafNode?.Parent as Group) != null;
    }

    private void OnDeleteLeaf(Leaf leafNode)
    {
        // Some code
    }

    public Command<Leaf> DeleteLeaf { get; private set; }
}

问题是,当最初构造Tree时,command参数始终为null,如果参数为null,则我的CanExecute测试返回false。因此,当我的树最初显示时,我的所有按钮都被禁用。

但是,如果我单击任何按钮,则会重新评估所有按钮并启用它们,因为现在正在正确传递命令参数。

我尝试过添加:

protected override Task InitializeAsync()
{
    CommandManager.InvalidateRequerySuggested();
    ViewModelCommandManager.InvalidateCommands(true);
    return base.InitializeAsync();
}

尝试在加载UI后重新评估所有命令,但这似乎不起作用。我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

尝试切换命令参数和命令对象的顺序。原因是CommandParameter不可绑定,并且不会引发任何更改通知。因此,在更新&#34;之后,不会重新评估该命令。 (它仍然是初始绑定过程)。

如果这不起作用,可以这样:

protected override async Task InitializeAsync()
{
    await base.InitializeAsync();

    _dispatcherService.BeginInvoke(() => ViewModelCommandManager.InvalidateCommands(true););
}