禁用右键单击并使用MVVM在WPF中启用左键单击上下文菜单

时间:2010-10-27 05:30:12

标签: wpf contextmenu

代码:

<Button Style="{StaticResource HPForegroundStyle}" IsTabStop="False"                 
        Command="{Binding ForegroundPhoneCommand}"  Click="Button_Click">
                    <Button.ContextMenu>                   
                        <ContextMenu ItemsSource="{Binding OptionsMenuItemList}"                            ItemContainerStyle="{StaticResource ContextMenuItemStyle}" 
                                     IsOpen="{Binding IsMenuOpen}"                                        
                                     PlacementTarget="{Binding RelativeSourc={RelativeSource AncestorType={x:Type Button}}}">
                        </ContextMenu>
                    </Button.ContextMenu>
    </Button>

我正在使用MVVM模式。在ViewModel中,我有一个属性'IsMenuOpen',它控制上下文菜单打开关闭。问题是我能够禁用右键单击而不能在左键单击时显示上下文菜单。

5 个答案:

答案 0 :(得分:21)

您还可以检查父控件上的ContextMenuService.IsEnabled附加属性。它将仅阻止右键单击,您仍然可以在左键单击时手动显示菜单,因此基于前面的示例:

<Button x:Name="btn" Click="btn_Click" ContextMenuService.IsEnabled="false">
    <Button.ContextMenu>
        <ContextMenu x:Name="popup">
         ...
        </ContextMenu>
    </Button.ContextMenu>
</Button>

private void btn_Click(object sender, RoutedEventArgs e)
{
    popup.Visibility = Visibility.Visible;
    popup.IsOpen = true;
}

答案 1 :(得分:2)

这对我来说使用类似于问题的XAML。

private bool _isMenuOpen = false;
public bool IsMenuOpen 
{
    get { return _isMenuOpen; }
    set 
    {
        // Don't allow the UI (right-click) to set this property to true
        if (!value)
            _isMenuOpen = value;
    }
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button btn = sender as Button;
    _isMenuOpen = true;
    btn.ContextMenu.IsOpen = true;
}

答案 2 :(得分:2)

要跟踪的一些事情:

  1. 确保ContextMenu的DataContext有效。
  2. 确保IsOpen是双向绑定。
  3. 如果您要尝试左键单击打开,请记住PlacementTarget无效,因此您必须设置Button.ContextMenu.PlacementTarget = this,然后设置IsMenuOpen = true才能显示它。
  4. 我的代码段供参考:

    <Style x:Key="SubjectButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource CommandButtonStyle}">
    <Setter Property="Foreground" Value="Green" />
    <Setter Property="ContextMenu">
        <Setter.Value>
            <ContextMenu DataContext="{Binding PlacementTarget.DataContext.Manager, RelativeSource={RelativeSource Self}}" 
                         ItemsSource="{Binding SubjectManager.ContextMenuItems}"
                         IsOpen="{Binding SubjectManager.ContextMenuIsOpen, Mode=TwoWay}">
                <ContextMenu.ItemContainerStyle>
                    <Style TargetType="MenuItem">
                        <Setter Property="Command" Value="{Binding OnClick}" />
                    </Style>
                </ContextMenu.ItemContainerStyle>
            </ContextMenu>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Foreground" Value="DarkGreen" />
        </Trigger>
    </Style.Triggers>
    </Style>
    

    在视图模型中:

    public void ShowContextMenu(SearchCondition searchCondition, Button button)
    {
        button.ContextMenu.DataContext = this;
        SubjectManager.OpenContextMenu();
    }
    

答案 3 :(得分:0)

如果要将菜单绑定到属性,请考虑使用Popup控件。它具有与上下文菜单类似的功能,但未绑定到特定的鼠标按钮...

<Popup IsVisible = {Binding IsMenuOpen} >
    <!-- Fill in what you need here -->
</Popup>

答案 4 :(得分:0)

你可以这样做:

<Button x:Name="btn" Click="btn_Click" MouseRightButtonDown="btn_MouseRightButtonDown">
    <Button.ContextMenu>
        <ContextMenu x:Name="popup" Visibility="Collapsed">
            <MenuItem Header="aaa"></MenuItem>
            <MenuItem Header="bbb"></MenuItem>
        </ContextMenu>
    </Button.ContextMenu>
</Button>

private void btn_Click(object sender, RoutedEventArgs e)
{
    popup.Visibility = Visibility.Visible;
    popup.IsOpen = true;
}

private void btn_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    popup.Visibility = Visibility.Collapsed;
}