对相关的ICommands进行分组

时间:2013-04-19 23:46:56

标签: c# wpf mvvm

我是C#的新手,这是我的第一个WPF项目。我正在关注this tutorial(使用他们的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"/>

以下是那些的ICommands:

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

我应该调查什么才能将类似的功能按钮(例如数字)组合到一个ICommand中,使用一种可以确定发送方的方法 - 同时仍然不会在文章警告的情况下将代码放在Window类中。

3 个答案:

答案 0 :(得分:3)

按钮的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; } }
}

就是这样。

FYI。

  1. 您似乎明确指定了按钮大小,这通常是一种不好的做法。要定位按钮,请使用堆栈或包装面板或grid / uniformgrid。
  2. 阅读有关样式和模板的信息,以增加代码重用。
  3. 示例:

     <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方式自动填充控件。
    2. 祝你好运!

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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

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作为参数的方法。