Overview
概观
I have a WPF application written in C# .NET 4.0. There are a number of buttons in this project. Currently, every EventHandler for the button click events calls the same method, with a different valued parameter. As this is all done in C# code, it is rather unwieldy and involves a lot of copy/paste.
我有一个用C#.NET 4.0编写的WPF应用程序。这个项目中有很多按钮。目前,按钮单击事件的每个EventHandler都使用不同的值参数调用相同的方法。因为这都是在C#代码中完成的,所以它相当笨拙并涉及大量的复制/粘贴。
I'd much rather use a Command, rather than a bunch of EventHandlers, as it keeps my code cleaner.
我宁愿使用Command而不是一堆EventHandler,因为它可以让我的代码更清晰。
Problem
问题
No matter what I do, I cannot get the XAML to accept the new command:
无论我做什么,我都无法让XAML接受新命令:
<Window.CommandBindings>
<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
</Window.CommandBindings>
The above code has an error: "CommandConverter cannot convert from System.String". This error exists on the Command="ButtonClick"
.
上面的代码有一个错误:“CommandConverter无法从System.String转换”。 Command =“ButtonClick”上存在此错误。
Research/Attempts
研究/尝试
I've tried everything I can think of to make this work to no avail. I've looked at at least 30 different blog posts/tutorials/etc. on how to properly do this, so I don't have an actual list for you. I saw some people using the Binding
keyword, so I attempted: Command="{Binding ButtonClick}"
, but apparently that's not allowed inside a CommandBinding section. I have also tried Command="{x:Static ButtonClick}"
, but that doesn't work either.
我已经尝试了所有我能想到的事情来使这项工作无济于事。我已经查看了至少30篇不同的博客文章/教程/等。关于如何正确地做到这一点,所以我没有适合你的实际清单。我看到有些人使用Binding关键字,所以我尝试了:Command =“{Binding ButtonClick}”,但显然在CommandBinding部分中不允许这样做。我也尝试过Command =“{x:Static ButtonClick}”,但这也不起作用。
As for the "ButtonClick" itself, I have tried several possible values there. "ButtonClick" is an arbitrary text string that does not correspond to any class/method/variable. My original understanding of this parameter was for the value to be simply an identifying string. I have also tried using an actual method in the same class "ButtonClick_Executed". I have also tried using a class name which implements ICommand (Commands), as well as a method inside that class (Commands.ButtonClick_Executed).
至于“ButtonClick”本身,我在那里尝试了几个可能的值。 “ButtonClick”是一个任意文本字符串,与任何类/方法/变量都不对应。我对这个参数的原始理解是,这个值只是一个识别字符串。我也尝试在同一个类“ButtonClick_Executed”中使用实际方法。我还尝试使用实现ICommand(命令)的类名,以及该类中的方法(Commands.ButtonClick_Executed)。
For reference, I also tried doing this in the codebehind as per WPF: Binding to commands in code behind, but I couldn't make that work either.
作为参考,我也尝试按照WPF在代码隐藏中执行此操作:绑定到后面的代码中的命令,但我也无法使其工作。
Code
码
Code is abridged to what is relevant. From what I understand, the Button's Command parameter needs to match the CommandBinding's Command value. I have not added this in yet, since I can't even get the CommandBinding to work. All code is in the same namespace, in a single project.
代码被删减到相关的内容。据我所知,Button的Command参数需要与CommandBinding的Command值匹配。我还没有添加它,因为我甚至无法使CommandBinding工作。所有代码都在同一个命名空间中,在一个项目中。
MainWindow.xaml:
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:
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:
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;
}
Any and all help is greatly appreciated. Please let me know if you require any additional information.
非常感谢任何和所有的帮助。如果您需要任何其他信息,请与我们联系。
Update I have attempted the answer proposed by Herdo. The new error I got was The namespace prefix "T9Messager" is not defined
. After research, my XAML now opens like this:
更新我尝试了Herdo提出的答案。我得到的新错误是未定义名称空间前缀“T9Messager”。经过研究,我的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">
This seems to have fixed that particular issue, but now it looks as if the XAML is completely ignoring the Command parameter. Command="T9Messager:Commands.ButtonClick"
creates the error Value cannot be null. Parameter name: value
.
这似乎解决了这个特定问题,但现在看起来好像XAML完全忽略了Command参数。 Command =“T9Messager:Commands.ButtonClick”创建错误值不能为null。参数名称:值。
1 个解决方案
#1
4
This ButtonClick
is a String
:
这个ButtonClick是一个字符串:
<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
You need to write it as a member of the class (note that you need to add the namespace in the window declaration):
您需要将其编写为类的成员(请注意,您需要在窗口声明中添加命名空间):
<Window xmlns:t9m="clr-namespace:T9Messager"
...>
<CommandBinding Command="t9m:Commands.ButtonClick"
Executed="ButtonClick_Executed" />
#1
4
This ButtonClick
is a String
:
这个ButtonClick是一个字符串:
<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
You need to write it as a member of the class (note that you need to add the namespace in the window declaration):
您需要将其编写为类的成员(请注意,您需要在窗口声明中添加命名空间):
<Window xmlns:t9m="clr-namespace:T9Messager"
...>
<CommandBinding Command="t9m:Commands.ButtonClick"
Executed="ButtonClick_Executed" />