【问题标题】:MenuItem visibility based on submenu item stateMenuItem 可见性基于子菜单项状态
【发布时间】:2020-02-06 20:24:37
【问题描述】:

我有一个基于 MVVM 的 WPF 上下文菜单,并希望将菜单项的可见性绑定到其子菜单项的 IsEnabled 属性。问题是:根MenuItem 始终可见,即使所有子菜单项都被禁用。但是在菜单项上移动光标会使其隐藏,我真的不知道为什么。

这是我的 xaml 代码:

<MenuItem x:Name="SelectionMenuItem" Header="{x:Static language:CommonRes.Selection}">
    <MenuItem.Visibility>
        <MultiBinding Converter="{StaticResource AnyBoolToVisibilityConverter}">
            <Binding
                ElementName="SelectGroupMenuItem"
                Mode="OneWay"
                Path="IsEnabled" />
            <Binding
                ElementName="SelectGraphMenuItem"
                Mode="OneWay"
                Path="IsEnabled" />
        </MultiBinding>
    </MenuItem.Visibility>

    <MenuItem
        x:Name="SelectGroupMenuItem"
        Command="{Binding SelectGroupCommand}"
        Header="{x:Static language:CommonRes.Group}"
        Visibility="{Binding IsEnabled, Converter={StaticResource BoolToVisibilityConverter}, RelativeSource={RelativeSource Self}}" />
    <MenuItem
        x:Name="SelectGraphMenuItem"
        Command="{Binding SelectGraphCommand}"
        Header="{x:Static language:CommonRes.ObjectGraph}"
        Visibility="{Binding IsEnabled, Converter={StaticResource BoolToVisibilityConverter}, RelativeSource={RelativeSource Self}}" />
</MenuItem>

和我的转换器的代码

public class AnyBoolToVisibilityConverter : IMultiValueConverter
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="values"></param>
    /// <param name="targetType"></param>
    /// <param name="parameter"></param>
    /// <param name="culture"></param>
    /// <returns></returns>
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if(!values.All(val => val is bool))
            return Visibility.Collapsed;

        return values.Any(val => (bool)val) ? Visibility.Visible : Visibility.Collapsed;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <param name="targetTypes"></param>
    /// <param name="parameter"></param>
    /// <param name="culture"></param>
    /// <returns></returns>
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException($"ConvertBack not Supported for {nameof(AnyBoolToVisibilityConverter)}");
    }
}

我希望你们中的一些人可以帮助我找到问题。

非常感谢。

【问题讨论】:

  • 如何更改MenuItemIsEnabled 属性?
  • CanExecute 返回值时,由命令绑定改变。这发生在初始化过程中。
  • 好的,在你的情况下,我们可以静态地将 IsEnabled 设置为 false 以重现问题吗?
  • 移除命令绑定,将所有子菜单项的IsEnabled属性静态设置为false即可。看起来子菜单项的绑定在它们出现之前不会被触及。知道为什么吗?
  • 可能是因为 CanExecuteChanged 没有提早提出。尝试手动引发事件?

标签: c# wpf xaml mvvm


【解决方案1】:

似乎PopupItems 不会评估它们的绑定,直到Popup 调用IsSubmenuOpenChanged 回调并在IsSubmenuOpen 属性更改后调用CommandManager.InvalidateRequerySuggested() (Source)。

所以我最终得到了另一个根命令MenuItem,它验证了所有子菜单命令的 CanExecute。

【讨论】:

  • 你应该将此标记为我认为的答案:) 不过调查它做得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-10
  • 2016-05-18
  • 2013-07-14
  • 2015-01-14
  • 2011-09-10
  • 2014-10-06
  • 2021-05-11
相关资源
最近更新 更多