1

概述

我有一个用 C# .NET 4.0 编写的 WPF 应用程序。这个项目中有许多按钮。目前,按钮单击事件的每个 EventHandler 都调用相同的方法,但具有不同的值参数。由于这一切都是在 C# 代码中完成的,因此相当笨拙并且涉及大量复制/粘贴。

我更愿意使用命令,而不是一堆事件处理程序,因为它使我的代码更干净。

问题

无论我做什么,我都无法让 XAML 接受新命令:

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

上面的代码有一个错误:“CommandConverter cannot convert from 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 的方式在代码隐藏中执行此操作,但我也无法使其工作。

代码

代码被删节为相关的内容。据我了解,Button 的 Command 参数需要与 CommandBinding 的 Command 值相匹配。我还没有添加这个,因为我什至无法让 CommandBinding 工作。所有代码都在同一个命名空间中,在一个项目中。

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;
    }
}

命令.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 回答