35

デモでは、bool フィールドを切り替えるボタンがありますisAsking。の場合にのみ実行できるコマンドを作成しますisAsking==true

トグル ボタンを押すと、okButton.IsEnableすぐに変更されます。これは、コマンドが の変更を検出したことを示していますisAsking

なぜコマンド オブジェクトがフィールドの変化に気付くのか、私は非常に困惑しています。いつCanExecute呼ばれますか?

しばらくWPFアプリケーションを書いていますが、WPFコマンドは初めてです。この場合の説明をお願いします。可能であれば、関連する記事やブログをいくつか指摘してください (切り取り/貼り付けコマンドについて説明している記事はすでにあまりにも多く読んでいます)。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="WpfApplication1.MainWindow"
        Title="MainWindow" Height="350" Width="525" x:Name="mainWindow" >
    <StackPanel>
        <Button Name="okButton" Content="Ok" />
        <Button Content="Toggle"  Click="Button_Click_1"/>
    </StackPanel>
</Window>

分離コード:

public partial class MainWindow : Window
{
    private bool isAsking;

    public MainWindow()
    {
        InitializeComponent();

        CommandBinding cb = new CommandBinding();
        cb.Command = okCommand;
        cb.CanExecute += CanOKExecute;
        cb.Executed += cb_Executed;
        mainWindow.CommandBindings.Add(cb);
        okButton.Command = okCommand;
    }

    private RoutedCommand okCommand = new RoutedCommand("ok", typeof(MainWindow));


    void cb_Executed(object sender, ExecutedRoutedEventArgs e)
    {
       
    }

    void CanOKExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = isAsking;
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        isAsking = !isAsking;
    }
}
4

4 に答える 4

40

技術的な答えは、イベントが発生CanExecuteするたびに呼び出されることです。CommandManager.RequerySuggestedドキュメントによると、これは...

...CommandManager が、コマンドの実行能力を変更する可能性のある条件を検出したとき。

実際には、これは がいつ呼び出されるかを気にする必要がないことを意味しますCanExecute。WPF は、それが適切であると判断したときにそれを呼び出します。私の経験では、これはほとんどの場合、要件を満たします。

これに対する例外はCanExecute、UI によってトリガーされない何かに基づいて戻り値を変更するバックグラウンド タスクがある場合です。このシナリオでは、手動で WPF ランタイムに再クエリCanExecuteを強制する必要がある場合があります。CommandManager.InvalidateRequerySuggested

于 2013-01-12T15:43:10.220 に答える
32

「CommandManager が条件を検出する」を検索して、この優れた記事に到達しようとしました。

.NET Framework のソース コードを調べると、作成者は、 、、、またはが発生CommandManagerした場合ではなく、それ自体で条件を検出するのではなく、CanExecute メソッドを再評価することを発見しました。Keyboard.KeyUpEventMouse.MouseUpEventKeyboard.GotKeyboardFocusEventKeyboard.LostKeyboardFocusEvent

この記事には他の情報も含まれていますが、上記の部分で十分です。

于 2013-01-13T02:39:40.923 に答える
9

RoutedCommandCanExecuteChangedイベントに内部的にフックするイベントが含まれていCommandManager.RequerySuggestedます -

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

そして、CommandManager.RequerySuggestedイベントが発生します

コマンドソースへの変更が、あなたの場合はウィンドウであるコマンドマネージャーによって検出されるたびに。したがって、ボタンがクリックされると、commandManager は RequerySuggested イベントを発生させ、コマンドに登録された CanExecute 述語を実行しました。

また、CommandManager には静的メソッドがありますInvalidateRequerySuggested。これにより、CommandManager は強制的に RequerySuggestedEvent を発生させます。したがって、それを呼び出してコマンドを手動で検証することもできます。

于 2013-01-13T08:34:08.903 に答える