【问题标题】:Suppressing right-click context menu on canvas抑制画布上的右键单击上下文菜单
【发布时间】:2015-04-01 12:55:32
【问题描述】:

我有一个画布,当用户右键单击它时,会出现一个上下文菜单。我还有一个复选框,当该框被选中时,我不希望出现上下文菜单。这样做的原因是,当复选框被选中时,用户的前两次右键单击将在右键单击的两个点上放置椭圆。不过现在,右键单击这两次会弹出上下文菜单。相关代码如下:

<Window x:Class="Testproj.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Testproj"
    xmlns:localConverters="clr-namespace:Testproj"
    x:Name="this"
    Height="650" Width="1091"
    Loaded="this_Loaded"
    Closing="this_Closing">

    <Window.Resources>
        <local:BoolToVisibilityConverter x:Key="converter"/>
    </Window.Resources>

<Grid Height="Auto">
    <Grid.Resources>
        <local:NullToVisibilityConverter x:Key="nullToVisibilityConverter" />
    </Grid.Resources>

    <Grid VerticalAlignment="Top">
        <DockPanel>
                <CheckBox x:Name="scaleBox" Content="Scale" IsChecked="False" Checked="scaleischecked"/>
            </Menu>
        </DockPanel>
    </Grid>

    <Viewbox Margin="0,23,0,157" x:Name="viewbox1" ClipToBounds="True">
        <Canvas Margin="0,21,0,12" x:Name="canvas1" ClipToBounds="True" RenderOptions.BitmapScalingMode="HighQuality" MouseWheel="Canvas_Zoom" MouseRightButtonDown="get_MousePosition"  HorizontalAlignment="Left" Width="3138" Height="1260">
            <Canvas.RenderTransform>
                <MatrixTransform x:Name="mt"/>
            </Canvas.RenderTransform>
            <Canvas.ContextMenu>
                <ContextMenu Name="nodeContextMenu" Visibility="{StaticResource converter}" >
                    <MenuItem x:Name="test1"  IsCheckable="False" Header="test1" Click="WaypointMenuItem_Click" >
                    </MenuItem>
                    <MenuItem x:Name="test2" IsCheckable="False" Header="test2" Click="KnownObjectMenuItem_Click" >
                    </MenuItem>
                </ContextMenu>
            </Canvas.ContextMenu>
        </Canvas>
    </Viewbox>
</Grid>
</Window>

以及右键单击画布的代码:

    private void get_MousePosition(object sender, MouseButtonEventArgs e)
    {
        if (scaleBox.IsChecked == true)
        {
            get_points(sender, e);
        }
    }

我尝试过使用上下文菜单的 isOpen 属性,但无论设置为 true 还是 false,它总是在右键单击时打开。

尝试下面的转换器。如果这是正确的,那么使用 this 绑定复选框和上下文菜单的正确方法是什么?

namespace Testproj
{
public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Visibility visibility = Visibility.Collapsed;
        if (value != null)
        {
            visibility = (bool)value ? Visibility.Collapsed : Visibility.Visible;
        }

        return visibility;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
}

【问题讨论】:

    标签: c# wpf canvas contextmenu right-click


    【解决方案1】:

    我会实现ValueConverterMultiValueConverter,然后使用转换器绑定到复选框以指示上下文菜单的状态(即启用/禁用)。

            <Canvas.ContextMenu>
                <ContextMenu Name="contextmenu1" Visibility="{Binding ElementName=scaleBox, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}" >
                    <MenuItem x:Name="item1"  IsCheckable="False" Header="item2" />
                    <MenuItem x:Name="item2" IsCheckable="False" Header="item1" />
                </ContextMenu>
    

    【讨论】:

    • 不太确定转换器是如何工作的,但我明白你的意思。还有另一种方法可以将复选框绑定到上下文菜单吗?我以前从未使用过转换器。
    • 你需要学习。否则,如果您不利用 XAML 模式,您将成为一名 XAML 开发人员。
    • 打算用转换器尝试编辑我的答案。你能告诉我这是否是正确的方法吗?
    • 您需要在 XAML 的资源部分中将 valueconverter 声明为资源。接下来,您按照我在回答中提供的 XAML 的 sn-p 操作。在您的 ValueConverter 实现上放置一个断点并逐步执行代码以了解您在加载应用程序时的逻辑。
    • 这是将其声明为资源的正确方法吗?因为在使用调试器单步执行时,我收到一条错误消息,指出无法解析资源。
    【解决方案2】:

    这是我想出的方法,因为我无法让转换器正常工作:

    在画布中将 ContextMenuService.IsEnabled 属性设置为 false。然后,在后面的代码中,在未选中 scalebox 时设置 nodeContextMenu.IsOpen = true 。这似乎可以解决问题。

    <Canvas Margin="0,21,0,12" x:Name="canvas1" ContextMenuService.IsEnabled="False" />
    
    if (scaleBox.IsChecked == true)
    {
        get_Scaling(sender, e);
    }
    else
    {
        nodeContextMenu.IsOpen = true;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-15
      • 2017-04-22
      • 1970-01-01
      相关资源
      最近更新 更多