2016-04-14 58 views
0

不知道這是不是我對WPF或Catel的理解,但是我有一個樹視圖,其中包含3個不同節點類型的數據模板。 2個節點類型可以綁定到一個刪除按鈕。按鈕命令的綁定綁定到父控件的視圖模型(而不是節點本身),並且該按鈕被點擊的節點的命令參數被傳遞。我提供的數據模板之一的小片段(整件事是太大,在此輸入):TreeView綁定節點上的按鈕CanExecute問題

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

視圖模型(又只是一個小摘錄):

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時,命令參數始終爲空,並且如果參數爲null,那麼我的CanExecute測試將返回false。所以當我的樹最初顯示時,我的所有按鈕都被禁用。

但是,如果我點擊任何按鈕,所有這些按鈕都會被重新評估並被啓用,因爲現在正在傳遞命令參數。

我曾嘗試加入:

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

在試圖重新評估的UI被加載後,但這似乎並沒有工作的所有命令。我在這裏錯過了什麼?

回答

0

嘗試切換命令參數和命令對象的順序。原因是CommandParameter不可綁定,並且不會引發任何更改通知。因此,該命令在「更新」後沒有被重新評估(它仍然是初始綁定過程)。

如果不工作,這樣的事情可能:

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

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

感謝您的建議海爾特,我想這兩個選項既不似乎工作。也許我需要更深入地調試源代碼。也許有些事情正在發生,這可以解釋爲什麼InvalidateCommand不像單擊鼠標那樣做同樣的事情。 – Bitfiddler

+0

嘗試使用對象作爲參數,而不是那天晚上幫助您找到問題 –

+0

嘗試使用對象,不幸的是,參數僅在第一次顯示樹時爲空。 – Bitfiddler