1

概要

C# .NET 4.0 で記述された WPF アプリケーションがあります。このプロジェクトにはいくつかのボタンがあります。現在、ボタン クリック イベントのすべての EventHandler は、異なる値のパラメーターを使用して同じメソッドを呼び出します。これはすべて C# コードで行われるため、かなり扱いにくく、多くのコピー/貼り付けが必要になります。

コードをきれいに保つため、一連の EventHandler ではなく Command を使用したいと思います。

問題

何をしても、XAML で新しいコマンドを受け入れることができません。

<Window.CommandBindings>
    <CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
</Window.CommandBindings>

上記のコードには、「CommandConverter は System.String から変換できません」というエラーがあります。このエラーは に存在しますCommand="ButtonClick"

研究・試み

この作業を無駄にするために、考えられるすべてのことを試しました。少なくとも 30 の異なるブログ投稿/チュートリアルなどを見てきました。これを適切に行う方法について説明しているので、実際のリストはありません。Bindingキーワードを使用している人を見たので、試してみました:Command="{Binding ButtonClick}"が、明らかに CommandBinding セクション内では許可されていません。私も試しCommand="{x:Static ButtonClick}"ましたが、それもうまくいきません。

「ButtonClick」自体については、いくつかの可能な値を試しました。「ButtonClick」は、どのクラス/メソッド/変数にも対応しない任意のテキスト文字列です。このパラメーターの最初の理解は、値が単なる識別文字列であるというものでした。同じクラス「ButtonClick_Executed」で実際のメソッドを使用してみました。また、ICommand (Commands) を実装するクラス名と、そのクラス内のメソッド (Commands.ButtonClick_Executed) を使用してみました。

参考までに、 WPF: Binding to commands in code behindに従って分離コードでこれを実行しようとしましたが、それも機能しませんでした。

コード

コードは関連するものに要約されています。私が理解していることから、ボタンの Command パラメーターは CommandBinding の Command 値と一致する必要があります。CommandBinding を機能させることさえできないため、これはまだ追加していません。すべてのコードは、1 つのプロジェクト内の同じ名前空間にあります。

MainWindow.xaml:

<Window x:Class="T9Messager.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="600" Width="540">
    <Window.CommandBindings>
        <CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
    </Window.CommandBindings>
    <Grid Margin="0,0,0,0">
        <Button x:Name="Button1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="165" Height="113">
            <TextBlock HorizontalAlignment="Center" TextAlignment="Center" FontSize="18" FontWeight="Bold">1</TextBlock>
        </Button>
        ... More buttons ...
    </Grid>
</Window>

MainWindow.xaml.cs:

public partial class MainWindow : Window, IObserver<Model>
{
    private Controller controller;

    private IDisposable Unsubscriber;

    public MainWindow()
    {
        Model model = new Model();
        Controller controller = new Controller(model);
        this.controller = controller; // MainWindow view = new MainWindow(c);
        Unsubscriber = model.Subscribe(this);

        InitializeComponent();
    }

    // This is the method I want to run
    public void ButtonClick_Executed(object sender, EventArgs ev)
    {
        Console.WriteLine("Command Executed");
    }
    // I want to avoid having a bunch of these
    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        controller.HandleButtonClick('1');
    }

    private void Button_Click_2(object sender, RoutedEventArgs e)
    {
        controller.HandleButtonClick('2');
    }

    ... More ButtonClick Events ...

    public void OnCompleted()
    {
        Unsubscriber.Dispose();
    }

    public void OnError(Exception error)
    {
        throw new NotImplementedException();
    }

    public void OnNext(Model value)
    {
        tb_text.Text = value.text;
    }
}

Commands.cs:

public class Commands : ICommand
{
    public Commands()
    {
        CommandBinding ButtonClickBinding = new CommandBinding(ButtonClickCommand);
        CommandManager.RegisterClassCommandBinding(typeof(Commands), ButtonClickBinding);
    }

    private RoutedUICommand ButtonClick = new RoutedUICommand("ButtonClick", "ButtonClick", typeof(Commands));

    public RoutedCommand ButtonClickCommand
    {
        get { return ButtonClick; }
    }

    // Getting any of the following 3 methods to execute would be fine
    public static void test()
    {
    }

    public void Execute(object parameter)
    {
        ButtonClick_Executed(null, null);
    }

    public void ButtonClick_Executed(object sender, EventArgs ev)
    {
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

}

どんな助けでも大歓迎です。追加情報が必要な場合はお知らせください。

更新 Herdo が提案した回答を試みました。私が得た新しいエラーはThe namespace prefix "T9Messager" is not defined. 調査の結果、私の XAML は次のように開きます。

<Window x:Class="T9Messager.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:T9Messager="clr-namespace:T9Messager"
    Title="MainWindow" Height="600" Width="540">

これにより、その特定の問題が修正されたように見えますが、XAML が Command パラメーターを完全に無視しているように見えます。 Command="T9Messager:Commands.ButtonClick"エラーを作成しますValue cannot be null. Parameter name: value

4

1 に答える 1

4

これButtonClickは次のStringとおりです。

<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />

クラスのメンバーとして記述する必要があります (ウィンドウ宣言に名前空間を追加する必要があることに注意してください)

<Window xmlns:t9m="clr-namespace:T9Messager"
        ...>

<CommandBinding Command="t9m:Commands.ButtonClick"
                Executed="ButtonClick_Executed" />
于 2014-03-16T15:42:12.560 に答える