Not sure if this is something I am not understanding about WPF or about Catel, but I have a treeview with 3 datatemplates for different node types. 2 of the node types can be bound to a delete button. The binding of the button command binds to the viewmodel of the parent control (rather than to the node itself) and a command parameter of the node where the button was clicked is passed. I am providing a small snippet of one of the data templates (the whole thing is too large to enter here):
<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 (again just a small extract):
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; }
}
The problem is that when the Tree is initially being constructed, the command parameter is always null, and my CanExecute test returns false if the parameter is null. So when my tree initially displays, all my buttons are disabled.
However, if I click any of the buttons, all of them get re-evaluated and become enabled because now the command parameter is being passed correctly.
I have tried adding:
protected override Task InitializeAsync()
{
CommandManager.InvalidateRequerySuggested();
ViewModelCommandManager.InvalidateCommands(true);
return base.InitializeAsync();
}
In an attempt to re-evaluate all the commands after the UI is loaded but this does not seem to work. What am I missing here?