Отключить правый клик и включить левый клик для контекстного меню в WPF с использованием MVVM - PullRequest
6 голосов
/ 27 октября 2010

Код:

<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 ]

21 голосов
/ 23 апреля 2014

Вы также можете проверить 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;
}
2 голосов
/ 24 июля 2013

Несколько вещей для отслеживания:

  1. Убедитесь, что DataContext из ContextMenu является действительным.
  2. Убедитесь, что IsOpen является двусторонней привязкой.
  3. Если вы попытаетесь открыть левый клик, помните, что PlacementTarget недопустим, поэтому вам нужно установить Button.ContextMenu.PlacementTarget = this, а затем IsMenuOpen = true, чтобы он появился. *

Мой фрагмент кода для справки:

<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();
}
2 голосов
/ 21 мая 2012

Это сработало для меня, используя 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;
}
0 голосов
/ 27 мая 2013

Вы можете сделать это так:

<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;
}
0 голосов
/ 28 октября 2010

Если вы хотите привязать меню к свойству, рассмотрите элемент управления Popup. Он имеет функции, аналогичные контекстному меню, но не привязан к конкретной кнопке мыши ...

<Popup IsVisible = {Binding IsMenuOpen} >
    <!-- Fill in what you need here -->
</Popup>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...