【问题标题】:WPF Context Menu pops up after Binding changes绑定更改后弹出 WPF 上下文菜单
【发布时间】:2017-05-26 10:20:53
【问题描述】:

我在 UserControl 中有一个 Border 控件,它用作图形更改的开关。边框有一个包含两个菜单项的上下文菜单:“打开”和“关闭”。

当开关关闭时,只有“打开”菜单项可见,而当开关打开时,只有“关闭”可见。对于某些开关,我需要完全禁用打开或关闭,因此我不希望它们在任何时候都可见。代码如下:

<Border.ContextMenu>
    <ContextMenu Name="switchContextMenu">
        <ContextMenu.Visibility>
            <MultiBinding Converter="{StaticResource ContextMenuBoolToVisibility}">
                <Binding Path="OpenAvailable" />
                <Binding Path="OpenVisible" />
                <Binding Path="CloseAvailable" />
                <Binding Path="CloseVisible" />
            </MultiBinding>
        </ContextMenu.Visibility>
        <MenuItem Name="miOpen" Header="{Binding Path=Resources.PowerControlSystem_OPEN, Source={StaticResource LocalizedStrings} }" 
                  Click="miOpen_Click">
            <MenuItem.Visibility>
                <MultiBinding Converter="{StaticResource BooleanToVisibilityMultiValueAND}">
                    <Binding Path="OpenAvailable" />
                    <Binding Path="OpenVisible" />
                </MultiBinding>
            </MenuItem.Visibility>
        </MenuItem>
        <MenuItem Name="miClose" Header="{Binding Path=Resources.PowerControlSystem_CLOSE, Source={StaticResource LocalizedStrings} }" 
                  Click="miClose_Click">
            <MenuItem.Visibility>
                <MultiBinding Converter="{StaticResource BooleanToVisibilityMultiValueAND}">
                    <Binding Path="CloseAvailable" />
                    <Binding Path="CloseVisible" />
                </MultiBinding>
            </MenuItem.Visibility>
        </MenuItem>
    </ContextMenu>
</Border.ContextMenu>

我将此开关用作通用组件,因此在另一个 .xaml 代码中我设置了“打开可用”和“关闭可用”属性。这是我的问题:

我有一个将 Open Available 属性设置为 False 的开关。默认情况下,此开关处于打开状态。我可以关闭它,没关系。然后,当我再次右键单击此开关时,上下文菜单不可见。这也行。

问题是当我更改一些值时,此开关再次打开,并且在那个时间点弹出上下文菜单。我认为问题在于 ContextMenu 可见性的转换器。它在此时被触发并且 ContextMenu 变得可见。

有人知道如何阻止这种行为吗?

【问题讨论】:

    标签: c# wpf contextmenu


    【解决方案1】:

    您可以设置Border 的样式,而不是设置ContextMenu 可见性

    <Border>
        <Border.Style>
            <Style TargetType="Border">
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu Name="switchContextMenu">
                            <MenuItem Name="miOpen" Header="{Binding Path=Resources.PowerControlSystem_OPEN, Source={StaticResource LocalizedStrings} }" 
                                Click="miOpen_Click">
                                <MenuItem.Visibility>
                                    <MultiBinding Converter="{StaticResource BooleanToVisibilityMultiValueAND}">
                                        <Binding Path="OpenAvailable" />
                                        <Binding Path="OpenVisible" />
                                    </MultiBinding>
                                </MenuItem.Visibility>
                            </MenuItem>
                            <MenuItem Name="miClose" Header="{Binding Path=Resources.PowerControlSystem_CLOSE, Source={StaticResource LocalizedStrings} }" 
                                Click="miClose_Click">
                                <MenuItem.Visibility>
                                    <MultiBinding Converter="{StaticResource BooleanToVisibilityMultiValueAND}">
                                        <Binding Path="CloseAvailable" />
                                        <Binding Path="CloseVisible" />
                                    </MultiBinding>
                                </MenuItem.Visibility>
                            </MenuItem>
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <DataTrigger Value="False">
                        <DataTrigger.Binding>
                            <MultiBinding Converter="{StaticResource ContextMenuBoolAggregate}">
                                <Binding Path="OpenAvailable" />
                                <Binding Path="OpenVisible" />
                                <Binding Path="CloseAvailable" />
                                <Binding Path="CloseVisible" />
                            </MultiBinding>
                        </DataTrigger.Binding>
                        <Setter Property="ContextMenu" Value="{x:Null}"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
    </Border>
    

    因此触发器有条件地删除ContextMenu,而不是更改其可见性。我使用了ContextMenuBoolAggregate 转换器名称来指示您需要创建一个新转换器来确定删除上下文菜单的正确值 - 我认为很清楚如何实现该部分。

    如果您的条件足够简单,您可以使用MultiDataTrigger 而不是DataTriggerMultiBindingConverter

    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding OpenAvailable}" Value="False"/>
            <Condition Binding="{Binding OpenVisible}" Value="False"/>
            <Condition Binding="{Binding CloseAvailable}" Value="False"/>
            <Condition Binding="{Binding CloseVisible}" Value="False"/>
        </MultiDataTrigger.Conditions>
        <Setter Property="ContextMenu" Value="{x:Null}"/>
    </MultiDataTrigger>
    

    【讨论】:

      【解决方案2】:

      我以另一种方式找到了解决方案。我使用了ContextMenuService.IsEnabled 属性。设置为 false 时,无法显示上下文菜单。所以,我在我的 Border.xaml 代码中添加了这个:

      <ContextMenuService.IsEnabled>
          <MultiBinding Converter="{StaticResource ContextMenuBoolToVisibility}">
              <Binding Path="OpenAvailable" ElementName="mySwitch" />
              <Binding Path="OpenVisible" ElementName="mySwitch" />
              <Binding Path="CloseAvailable" ElementName="mySwitch" />
              <Binding Path="CloseVisible" ElementName="mySwitch" />
          </MultiBinding>
      </ContextMenuService.IsEnabled>
      

      我还更改了我的ContextMenuBoolToVisibility 转换器。不再返回 Visibility.VisibleVisibility.Collapsed,而是为 ContextMenuService.IsEnabled 属性返回 truefalse

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-20
        • 1970-01-01
        • 1970-01-01
        • 2018-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-08
        相关资源
        最近更新 更多