概要
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
。