对相关ic命令进行分组

本文关键字:命令 ic | 更新日期: 2023-09-27 18:10:09

我是c#新手,这是我的第一个WPF项目。我遵循本教程(使用他们的RelayCommand实现并尝试使用MVVM)。我正在实现一个标准Windows计算器的克隆。我想找到一种方法来组类似按钮的功能,因为我正在做的事情似乎很笨拙。

例如,这是我的三个按钮的XAML

<Button Content="_7" Focusable ="False" Command="{Binding Seven}" Style="{DynamicResource NumberButton}" Margin="0,134,184,129"/>
<Button Content="_8" Focusable ="False" Command="{Binding Eight}" Style="{DynamicResource NumberButton}" Margin="46,134,138,129"/>
<Button Content="_9" Focusable ="False" Command="{Binding Nine}" Style="{DynamicResource NumberButton}" Margin="92,134,92,129"/>

下面是这些的iccommands:

public ICommand Nine { get { return new RelayCommand(NineExecute); } }
public ICommand Eight { get { return new RelayCommand(EightExecute); } }
public ICommand Seven { get { return new RelayCommand(SevenExecute); } }

和方法:

void NineExecute()
{
   NumberPressed("9");
}
void EightExecute()
{
   NumberPressed("8");
}
void SevenExecute()
{
   NumberPressed("7");
}

为了将类似的功能按钮(如数字)分组到一个单一的iccommand中,使用一个可以确定发送者的方法-同时仍然不像文章警告的那样将代码放在窗口类中,我应该调查什么?

对相关ic命令进行分组

按钮的Xlam代码(假设您定义了数据上下文):

    <....DataContext>
        <loc:Commands/>
    </....DataContext>
    <Button Content="_9" 
            Command="{Binding Path=ShowMeABox}" 
            CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Content}"/>

我们的虚拟命令(使用提供的链接中的RelayCommand<T>):

public class Commands
{
    private static readonly ICommand _showShowBoxCommand = 
        new RelayCommand<string>(str => MessageBox.Show(str));
    public static ICommand ShowMeABox { get { return _showShowBoxCommand; } }
}

供参考。

  1. 似乎你明确指定按钮大小,这通常是一个不好的做法。要定位您的按钮使用堆栈或包裹面板,或网格/uniformgrid。
  2. 阅读关于样式和模板的信息,以增加代码的重用。

的例子:

 <UniformGrid Columns="3" Rows="3">
    <UniformGrid.DataContext>
        <loc:Commands/>
    </UniformGrid.DataContext>
    <UniformGrid.Resources>
        <Style TargetType="Button">
            <Setter Property="Command" Value="{Binding ShowMeABox}"/>
            <Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Content}"/>
        </Style>
    </UniformGrid.Resources>
    <Button Content="_1"/>
    <Button Content="_2"/>
    <Button Content="_3"/>
    <Button Content="_4"/>
    <Button Content="_5"/>
    <Button Content="_6"/>
    <Button Content="_7"/>
    <Button Content="_8"/>
    <Button Content="_9"/>
</UniformGrid>

  1. 可能绑定Enumerable.Range(0,10)以MVVM方式自动填充控件。

祝你好运!

使用CommandParameter属性-这样您可以将所有按钮绑定到相同的命令,但对于每个数字使用不同的CommandParameter(即,CommandParameter应该是一个整数,表示实际按下的按钮)

我个人会使用构造函数来编写:

public YourType()
{
    this.Seven = new RelayCommand( () => NumberPressed("7"));
    this.Eight = new RelayCommand( () => NumberPressed("8"));
    this.Nine = new RelayCommand( () => NumberPressed("9"));
}
public ICommand Nine { get; private set; }
public ICommand Eight { get; private set; }
public ICommand Seven { get; private set; }

注意,使用CommandParameter和单个命令也可能有意义。许多框架提供了RelayCommand/ActionCommand/etc的变体,它们接受命令参数,然后可以在XAML中指定。这个特定的实现不允许这样做,但是很多实现都允许,并且将映射到一个直接将CommandParameter作为参数的方法。