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

本文关键字:程序 获取 IsChecked 属性 事件处理 检查 菜单项 | 更新日期: 2023-09-27 18:31:39

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

XAML:

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

视图模型(不包括用于错误恢复的代码):

public IEnumerable<IResult> ToggleLaser(bool isChecked)
{
    yield return BusyResult.Show("Turning laser " + (isChecked ? "on" : "off");
    if (isChecked) 
        yield return TurnOnLaserAsync().AsResult();
    else
        yield return TurnOffLaserAsync().AsResult();            
    LaserState = isChecked;
    yield return BusyResult.Hide();
}

这不起作用 - isChecked完全是错误的。

我可以得到事件参数:

public IEnumerable<IResult> ToggleLaser(RoutedEventArgs eventArgs)
{
    var menuItem = (MenuItem)eventArgs.OriginalSource;
    var isChecked = menuItem.IsChecked;
    return ToggleLaser(isChecked);
}

但是我的视图模型绑定到我的观点 - 不好。

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

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

我想出的一个解决方案是通过添加新的数据绑定关键字来扩展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)"/>

我的视图模型变成了

public void ToggleLaser(bool turnOn)
    {
        if (turnOn)
            TurnOnLaser();
        else
            TurnOffLaser();
    }

好多了。

我想第二种选择是数据绑定菜单项 IsChecked 属性 - 这有利于处理打开激光时出现问题的情况 - 但我不喜欢在属性设置器中调用复杂函数,所以我认为更好的解决方案是数据绑定 IsChecked 并使用特定的处理程序。

非常感谢评论。

MenuItem 包含 IsChecked 属性。

您只需执行以下操作:

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

它比创建一些MessageBinder更简单。