4

コマンドの実行後にイベントを実行できるようにする方法を探しています。私は EditingCommands (ToggleBold、ToggleItalic... など) を使用しており、コマンドが何をしていても終了した直後にメソッドを呼び出すことができるようにしたいと考えています。

たとえば、テキストを選択して Ctrl+B を押すと、EditingCommands.ToggleBold が実行されます。テキストが切り替えられた直後に、選択された FontWeight に接続されている ToggleButton を更新するメソッドを呼び出したいと思います。

イベントを使用してみExecutedましたが、残念ながら、テキストが影響を受ける前に呼び出され、その結果、わずか 1 秒で変更される情報でボタンが更新されます。誰もこれを回避する方法を知っていますか?

4

2 に答える 2

4

回避策は、Executed ハンドラーで別のメッセージをキューに入れることです。

void copy_Executed(object sender, EventArgs e)
{
    Dispatcher.BeginInvoke(new ThreadStart(delegate()
    {
        //do update of bold button here
    }), null);
}

これにより、作業がキューの最後に追加され、同じまたはより高い優先度の他のメッセージの後に実行されます。

ただし、より良い解決策を提案したいと思います。考えてみれば、太字ボタンは 2 つの異なるコマンドを実行する役割を担っています。太字にするコマンドと標準にするコマンドです。現在選択されているテキスト/キャレットの位置に基づいて、これら 2 つのコマンドを切り替えます。したがって、2 つのサブコマンドをカプセル化するカスタム実装を作成できICommandます (完全にテストされていないコード)。

public class TogglingCommand : ICommand
{
    private readonly ICommand _command1;
    private readonly ICommand _command2;
    private ICommand _activeCommand;

    public TogglingCommand(ICommand command1, ICommand command2)
    {
        _command1 = command1;
        _command2 = command2;
    }

    public ICommand ActiveCommand
    {
        get { return _activeCommand; }
    }

    public bool CanExecute(object parameter)
    {
        if (_command1.CanExecute(parameter))
        {
            _activeCommand = _command1;
        }
        else if (_command2.CanExecute(parameter))
        {
            _activeCommand = _command2;
        }
        else
        {
            _activeCommand = null;
        }

        return _activeCommand != null;
    }

    public void Execute(object parameter)
    {
        _activeCommand.Execute(parameter);
    }
}

TogglingCommand次に、テキストを太字にするコマンドと太字にするコマンドの 2 つのコマンドでaを作成できます。Button次に、UI の をプロパティにバインドしてActiveCommand、コマンドをクリックしたときに何が起こるかに基づいて、好きなように変更できます。たとえば、ToggleButtonバインドIsCheckedActiveCommandて変換するを使用している場合true、アクティブなコマンドは太字で表示されません。もちろん、太字コマンドと太字コマンドCanExecuteには、選択したテキストを検査する独自のロジックが必要です。

于 2009-03-29T10:28:41.063 に答える
0

実行済み (過去形) ルーティング イベント ハンドラーを使用できますか? (または、それはあなたが試したと言っていることかもしれません)

public partial class CustomerWindow : Window
{
    public CustomerWindow()
    {
        InitializeComponent();

        CommandBinding binding = new CommandBinding(ApplicationCommands.Copy);
        binding.Executed += new ExecutedRoutedEventHandler(this.copy_Executed);
        this.CommandBindings.Add(binding);
    }

    void copy_Executed(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Executed the Copy command");
    }
} 
于 2009-03-29T09:44:01.217 に答える