【问题标题】:Binding commands to ToggleButton Checked and Unchecked events将命令绑定到 ToggleButton Checked 和 Unchecked 事件
【发布时间】:2014-11-04 21:24:58
【问题描述】:

我的 C# WPF 应用程序中有一个 ToggleButton,我想将一个命令绑定到 Checked 事件,并将一个 Command 绑定到 Unchecked 事件。

我目前拥有的如下:

<ToggleButton Name="btnOpenPort" Style="{StaticResource myOnOffBtnStyle}" Content="Open Port"
              Checked="btnOpenPort_Checked" Unchecked="btnOpenPort_Unchecked"
              IsChecked="{Binding Path=PortViewModel.PortIsOpen, Mode=OneWay}"
              Canvas.Left="75" Canvas.Top="80" Height="25" Width="100"/>

但这不是我的目标。因为在这种情况下,我必须在代码中为 Checked 和 Unchecked 事件设置属性。 相反,一旦 Checked 或 Unchecked 事件被触发,我想在我的 ViewModel 中调用一个命令 (ICommand),这样我的切换按钮就不需要任何代码隐藏。

有没有办法在 XAML 中直接为这两个事件绑定命令? 类似于WPF中“标准”按钮控件的command属性?

编辑 这就是 @har07 提示的工作方式:

1:如果您还没有,请添加参考:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"

2:为选中和未选中事件实现了 Interaction.Triggers:

<ToggleButton 
        Name="btnOpenPort" Style="{StaticResource myOnOffBtnStyle}" Content="Open Port"
        IsChecked="{Binding Path=PortViewModel.PortIsOpen, Mode=OneWay}"
        Canvas.Left="75" Canvas.Top="80" Height="25" Width="100">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Checked">
                <i:InvokeCommandAction Command="{Binding Path=PortViewModel.OpenPort}"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="Unchecked">
                <i:InvokeCommandAction Command="{Binding Path=PortViewModel.ClosePort}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
</ToggleButton>

使用此解决方案,我无需更改 ViewModel 中的一行代码或我的代码。 我可以像使用遵循 MVVM 模式的标准按钮一样调用我的 ICommand。

【问题讨论】:

    标签: wpf xaml command togglebutton


    【解决方案1】:

    您可以将处理选中/未选中事件的逻辑放在PortIsOpen属性的设置器中:

    private bool _portIsOpen;
    public bool PortIsOpen
    {
        get { return _portIsOpen; }
        set
        {
            if(value) HandleCheckedEvent();
            else HandleUnCheckedEvent();
            ....
        }
    }
    

    或者您可以使用Ineraction.Triggers 扩展名将事件绑定到命令: WPF Binding UI events to commands in ViewModel

    【讨论】:

    • 我用 Ineraction.Triggers 实现了它。这简直完美!它正是我需要的!非常感谢!
    【解决方案2】:
     <ToggleButton Name="btnOpenPort" Style="{StaticResource myOnOffBtnStyle}" Content="Open Port"
                  Checked="{Binding ICommand}"  Unchecked="{Binding ICommand}"
                  IsChecked="{Binding Path=PortViewModel.PortIsOpen, Mode=OneWay}"
                  Canvas.Left="75" Canvas.Top="80" Height="25" Width="100"/>
    

    将 ICommand 替换为您的 ICommand 属性名称。

    【讨论】:

    • 这种方法会引发 XamlParseException - '在 'System.Windows.Data.Binding' 上提供值引发异常。'- 指向我绑定 ICommand 的行。 {"无法将'System.Reflection.RuntimeEventInfo'类型的对象转换为'System.Reflection.MethodInfo'类型。"} .
    【解决方案3】:

    您可能无法直接为每个已选中和未选中的命令绑定两个命令,但是您仍然可以绑定一个命令,该命令将为两者调用。如果您需要两个事件的不同命令,您还可以选择附加行为。

    <ToggleButton Command="{Binding MyCommand}"/>
    

    在虚拟机中

    public ICommand MyCommand { get; private set; }
    

    你需要相应地初始化它

    要确定当前状态,您可能对保税财产PortIsOpen 有一个条件

    void Execute(object state)
    {
        if(PortIsOpen)
        {
            //checked
        }
        else
        {
            //unchecked
        }
    }
    

    或者你也可以将它作为参数传递

    例如

    <ToggleButton Command="{Binding MyCommand}" 
                  CommandParameter="{Binding IsChecked,RelativeSource={RelativeSource Self}}"/>
    

    并将其用作

    void Execute(object state)
    {
        if((bool)state)
        {
            //checked
        }
        else
        {
            //unchecked
        }
    }
    

    【讨论】:

      【解决方案4】:

      也许我们可以使用 EventTriggers

          <ToggleButton>
              <i:Interaction.Triggers>
                  <i:EventTrigger EventName="Checked">
                      <i:InvokeCommandAction Command="{Binding Path=CheckedCommand}"/>
                  </i:EventTrigger>
                  <i:EventTrigger EventName="Unchecked">
                      <i:InvokeCommandAction Command="{Binding Path=UncheckedCommand}"/>
                  </i:EventTrigger>
              </i:Interaction.Triggers>
          </ToggleButton>
      

      要使用触发器,我们必须引用System.Windows.Interactivity

       xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
      

      【讨论】:

      • 谢谢,这正是我所做的。 @har07 的链接正是指这种方法。我刚刚在几分钟前更新了我的帖子,完全采用了这种方法!
      • 很高兴您解决了您的问题,对不起,我不是要重复发帖,我没有看到提供的链接
      猜你喜欢
      • 2010-10-30
      • 1970-01-01
      • 2020-12-27
      • 1970-01-01
      • 2012-06-11
      • 2014-11-06
      • 1970-01-01
      • 2014-12-02
      • 2018-01-19
      相关资源
      最近更新 更多