簡體   English   中英

當我將CommandParameter設置為某個Binding時,為什么我的ICommand.CanExecute(object)參數為null,但當我將其設置為某個靜態值時為非null?

[英]Why is my ICommand.CanExecute(object) parameter null when I set CommandParameter to some Binding, but non-null when I set it to some static value?

我正在學習WPF中的ICommands,我遇到了一些簡單代碼的問題。 我有一個帶命令的按鈕。 如果我將command參數設置為這樣的靜態值, CommandParameter="100" ,則CanExecute中parameter參數的值為100,但是當我通過綁定設置命令參數的值時,如此CommandParameter="{Binding}" ,CanExecute中parameter參數的值為null。

這是我的ICommand:

internal class MyCommand : ICommand
{
    public bool CanExecute(object parameter) //parameter is null
    {
        var datacontext = parameter as MyDataContext;
        if (datacontext == null)
            return false;

        return datacontext.IsChecked == true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        throw new NotImplementedException();
    }
}

這是XAML代碼。 請注意,我在設置Command之前設置了CommandParameter。 從這里得到了。 同樣,如果我將CommandParameter更改為類似於CommandParameter="100" ,則代碼將按照我的預期運行(即參數為100,而不是null)。

<StackPanel Orientation="Vertical">
    <StackPanel.Resources>
        <cmd:MyCommand x:Key="kCmd" />
    </StackPanel.Resources>

    <CheckBox Content="Check this to enable button" IsChecked="{Binding IsChecked}" />
    <Button Content="Click" CommandParameter="{Binding}" 
            Command="{StaticResource kCmd}" />
</StackPanel>

這是我的MainWindow代碼隱藏。 在這里,我在調用InitializeComponent()之前設置DataContext。 在調試時,我發現InitializeComponent()觸發了對ICommand的CanExecute(object)的調用。

public MainWindow()
{
    this.DataContext = new MyDataContext();
    InitializeComponent();
}

我的MyDataContext類非常簡單,所以我把它留了下來。

它也是一種解決方案,通過引發命令的CanExecuteChanged事件, CanExecuteLoadedFrameworkElement事件中重新評估CanExecute 當您使用DataTemplate時,尤其可以使用此方法,並且您遇到此問題。

例:

 <DataTemplate x:Key="MyTemplate">
            <Grid Loaded="HandleLoaded">
 ...

和代碼背后:

 void HandleLoaded(object sender, RoutedEventArgs e)
 {
     var viewModel = this.DataContext as ViewModel;
     if (viewModel != null)
     {
         viewModel.DoItCommand.RaiseCanExecuteChanged();
     }
 }

另一種可行的解決方案是將命令本身的綁定定義為IsAsync=True 但這會導致一些閃爍。 所以這可能不是最好的選擇。

示例: {Binding DoItCommand, IsAsync=True}

InitializeComponent()完成后嘗試提升MyCommand類的CanExecuteChanged -event。 可能會調用MyCommandCanExecute(object)來在第一次渲染時初始化按鈕的狀態,而綁定尚未初始化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM