C# 如何在可检查菜单项的事件处理程序中获取IsChecked属性

C# 如何在可检查菜单项的事件处理程序中获取IsChecked属性,c#,wpf,xaml,caliburn.micro,C#,Wpf,Xaml,Caliburn.micro,我正在使用Caliburn.Micro,希望添加一个可检查的菜单项。此操作的处理程序需要知道菜单项的状态是否为选中状态 XAML: ViewModel(不包括错误恢复代码): public IEnumerable ToggleLaser(布尔值已检查) { 产量返回业务结果显示(“转动激光器”+(是否检查?“打开”):“关闭”); 如果(已检查) 收益返回TurnOnLaserAsync().AsResult(); 其他的 产生返回关断LaserAsync().AsResult(); 激光状

我正在使用Caliburn.Micro,希望添加一个可检查的菜单项。此操作的处理程序需要知道菜单项的状态是否为选中状态

XAML:


ViewModel(不包括错误恢复代码):

public IEnumerable ToggleLaser(布尔值已检查)
{
产量返回业务结果显示(“转动激光器”+(是否检查?“打开”):“关闭”);
如果(已检查)
收益返回TurnOnLaserAsync().AsResult();
其他的
产生返回关断LaserAsync().AsResult();
激光状态=已检查;
收益返回BusyResult.Hide();
}
这不起作用-isChecked始终是错误的

我可以得到事件参数:

public IEnumerable<IResult> ToggleLaser(RoutedEventArgs eventArgs)
{
    var menuItem = (MenuItem)eventArgs.OriginalSource;
    var isChecked = menuItem.IsChecked;
    return ToggleLaser(isChecked);
}
public IEnumerable ToggleLaser(RoutedEventArgs事件参数)
{
var menuItem=(menuItem)eventArgs.OriginalSource;
var isChecked=menuItem.isChecked;
返回开关激光器(已检查);
}
但是我的viewmodel绑定到我的视图-不好


我在这里找不到一个好的答案,所以将其发布在那里,因为我确信这是菜单项的一个非常正常的用例。

我提出的一个解决方案是通过添加一个新的数据绑定关键字来扩展caliburn框架:

        MessageBinder.SpecialValues.Add("$ischecked", context =>
        {
            var args = context.EventArgs as RoutedEventArgs;
            if (args == null) {
                return null;
            }
            var fe = args.OriginalSource as MenuItem;
            if (fe == null) {
                return null;
            }
            return fe.IsChecked;
        });
然后我的XAML变成:

<MenuItem Header="Laser" x:Name="ToggleLaser" VerticalAlignment="Top" IsCheckable="True" cal:Message.Attach="ToggleLaser($ischecked)"/>
好多了。:-)

我想第二种选择是对menuitem IsChecked属性进行数据绑定-这有利于处理在打开激光器时出错的情况-但我不喜欢在属性设置器中调用复杂函数,因此我认为更好的解决方案是对menuitem IsChecked进行数据绑定并使用特定的处理程序

非常感谢您的评论。

包含属性

您可以简单地执行以下操作:

<MenuItem Header="Laser"
          x:Name="ToggleLaser" 
          VerticalAlignment="Top"
          IsCheckable="True"
          IsChecked="{Binding IsLaserOn}">

它比创建一些MessageBinder更简单。

为什么不使用像
这样的标准绑定?caliburn中发生了一些变化?你是对的-标准绑定工作-我的问题不清楚-问题是切换激光需要时间-将更新问题中的代码-我同意-更简单。然而:我的问题是切换激光需要时间,而且可能会失败。因此,我想使用Enumerable命令将其传递给用户-我将更新代码样本您在这里有几个选项-您可以显式使用TPL,或者在创建绑定时使用IsAsync属性。
<MenuItem Header="Laser" x:Name="ToggleLaser" VerticalAlignment="Top" IsCheckable="True" cal:Message.Attach="ToggleLaser($ischecked)"/>
public void ToggleLaser(bool turnOn)
    {
        if (turnOn)
            TurnOnLaser();
        else
            TurnOffLaser();
    }
<MenuItem Header="Laser"
          x:Name="ToggleLaser" 
          VerticalAlignment="Top"
          IsCheckable="True"
          IsChecked="{Binding IsLaserOn}">
public bool IsLaserOn
{
    get { return this.isLaserOn; }
    set
    {
        if (value == this.isLaserOn)
            return;

        this.isLaserOn = value;
        this.RaisePropertyChanged("IsLaserOn");
        this.ToggleLaser(this.isLaserOn);
    }
}