【问题标题】:RoutedEvents and Commands路由事件和命令
【发布时间】:2014-10-06 16:04:22
【问题描述】:

我正在开发一个带有 RGB 选择器的 MVVM 应用程序。我每个通道有 3 个滑块,我想使用路由事件来捕捉每个滑块上的 ValueChanged 事件

<StackPanel Grid.Row="0" Grid.Column="1" Slider.ValueChanged="DoSmth">
    <Slider Value="{Binding R}" Minimum="0" Maximum="255" />
    <Slider Value="{Binding G}" Minimum="0" Maximum="255" />
    <Slider Value="{Binding B}" Minimum="0" Maximum="255" />
</StackPanel>

现在,这是一个 MVVM 应用程序,我想为此使用命令。但是,我无法找到一种无需将命令单独分配给每个滑块即可发送命令的方法。我读了一些关于“路由命令”的文章,但这也没有给我一个解决方案。

我怎样才能做到这一点?

【问题讨论】:

  • 为什么不向每个滑块添加相同的命令?您不需要任何参数,因为您已经绑定了 R、G 和 B,因此处理命令的方法可以处理这些属性,而不是处理参数。
  • 它甚至不需要参数,要执行的代码对于堆栈面板中的所有滑块都是相同的。我也很关心可伸缩性,我需要更多的滑块来设置其他参数,这就是我不想要任何冗余代码的原因。
  • 我说它不需要参数,是的,所有滑块的代码都是相同的。这就是为什么我说将相同的命令绑定到每个滑块,也是为什么我说你不需要任何参数。并且代码不是多余的:当您移动红色滑块时,您希望发生一些事情。您还希望在移动绿色或蓝色滑块时发生同样的事情,那么除非您在这些滑块上连接命令,否则您将如何传达应该发生的事情?
  • 正如我提到的那样:Routed Events。如果我可以通过在每个滑块上设置一个参数来将事件连接到命令,那可能仍然没问题,但是如果我每次都必须复制粘贴相同的触发器(如此处所示here),我会看到我的代码添加更多滑块时会变得非常混乱

标签: c# wpf events mvvm


【解决方案1】:

如果您坚持使用ICommand,那么您应该使用附加属性包装Slider.ValueChanged 事件。您可以在我对What's the best way to pass event to ViewModel? 问题的回答中了解如何做到这一点。

但是,您真的不需要使用任何ICommand...当然,每次视图模型中的数据绑定属性之一发生更改时,您都可以创建一个新的Color?此示例使用户无需使用任何ICommands 即可更改颜色:

<StackPanel Grid.Row="0" Grid.Column="1">
    <Slider Value="{Binding R}" Minimum="0" Maximum="255" />
    <Slider Value="{Binding G}" Minimum="0" Maximum="255" />
    <Slider Value="{Binding B}" Minimum="0" Maximum="255" />
    <Rectangle HorizontalAlignment="Stretch" Height="100">
        <Rectangle.Fill>
            <SolidColorBrush Color="{Binding Color}" />
        </Rectangle.Fill>
    </Rectangle>
</StackPanel>

在视图模型中:

private byte r = 127, g = 127, b = 127;
public byte R
{
    get { return r; }
    set { r = value; Color = Color.FromArgb((byte)255, R, G, B); NotifyPropertyChanged("R"); }
}
public byte G
{
    get { return g; }
    set { g = value; Color = Color.FromArgb((byte)255, R, G, B); NotifyPropertyChanged("G"); }
}
public byte B
{
    get { return b; }
    set { b = value; Color = Color.FromArgb((byte)255, R, G, B); NotifyPropertyChanged("B"); }
}
private Color color = Colors.Black;
public Color Color
{
    get { return color; }
    set { color = value; NotifyPropertyChanged("Color"); }
}

【讨论】:

  • 是的,我想我实际上可以这样做...我担心循环依赖/更新,因为在Colorset 中,我已经调用了滑块​​上的更新,这就是我设置直接在颜色sethandler 中支持属性...但是我可能会添加一些不影响显示颜色的推子,从而终止此解决方案。我将尝试其他解决方案并报告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多