2016-08-31 3 views
0

Я нашел одну ошибку, и я не понимаю, почему это происходит. У меня есть DataGrid. Щелкнув левой кнопкой мыши, я хочу открыть ContextMenu. Я сделал это. Он отлично работает, пока я не нажимаю на ячейки DataGrid в случайном порядке (каждый раз, когда ContextMenu закрывается и снова появляется на новом месте). Но в какой-то момент что-то происходит, а ContextMenu более новый показывается (и Window не реагирует на какие-либо события мыши, такие как нажатие на кнопки и т. Д.) ... пока я не вывожу курсор из окна и не верну его (или нажав Alt или F10) ,WPF ContextMenu проглатывает все события мыши

Вот некоторый код:
ContextMenu (внутри <DataGrid.Resources>)

<ContextMenu Style="{StaticResource DefaultContextMenuStyle}" x:Key="cm" 
    DataContext="{Binding Data, Source={StaticResource WindowViewModel}}"> 
</ContextMenu> 

DataGrid колонок:

<DataGridTemplateColumn Header="TestHeader" Width="*"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <DockPanel ContextMenu="{StaticResource cm}" VerticalAlignment="Stretch" Background="Transparent"> 
       <i:Interaction.Behaviors> 
        <local:OpenContextMenuLeftBehavior /> 
       </i:Interaction.Behaviors> 
       <TextBlock Style="{StaticResource TextVCenteredCellStyle}" Text="{Binding LPU}" /> 
      </DockPanel> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 

и поведение, чтобы открыть ContextMenu:

public class OpenContextMenuLeftBehavior : Behavior<FrameworkElement> 
{ 
    protected override void OnAttached() 
    { 
     AssociatedObject.PreviewMouseUp += OpenContextMenu; 
    } 

    protected override void OnDetaching() 
    { 
     AssociatedObject.PreviewMouseUp -= OpenContextMenu; 
    } 

    void OpenContextMenu(object sender, MouseButtonEventArgs e) 
    { 
     if (e.ChangedButton == MouseButton.Left) { 
      FrameworkElement Sender = sender as FrameworkElement; 
      Sender.ContextMenu.PlacementTarget = Sender; 
      Sender.ContextMenu.IsOpen = true; 
     } 
    } 
} 

Когда я обнаружил, что ошибка , Я попытался найти информацию со Snoop WPF. А вот некоторая информация из него:

  1. Перед плохо случилось один щелчок на ячейке было как:
    before bad thing

  2. После плохо:
    after bad thing
    Первое событие произошло в Popup (ContextMenu part?), он не принадлежит окну VisualTree. Этот всплывающее окно, кажется, растягивается по всему главному окну и закрывается, когда я выхожу из него.

Таким образом, я потерял 2 дня на том, что ошибка, и это все, что я могу найти.
Пожалуйста, помогите мне.

EDIT: я создал минимальный пример:

XAML: за

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
     xmlns:local="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <DataGrid x:Name="dg1" IsReadOnly="True"> 
      <DataGrid.Columns> 
       <DataGridTemplateColumn Width="*"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <DockPanel> 
           <i:Interaction.Behaviors> 
            <local:OpenContextMenuLeftBehavior /> 
           </i:Interaction.Behaviors> 
           <DockPanel.ContextMenu> 
            <ContextMenu> 
             <MenuItem Header="123456"></MenuItem> 
            </ContextMenu> 
           </DockPanel.ContextMenu> 
           <TextBlock Text="123" /> 
          </DockPanel> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 

Код:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     dg1.ItemsSource = new List<int>() 
     { 
      1,2,3,4,5,6,7,8,9,0 
     }; 
    } 
} 

public class OpenContextMenuLeftBehavior : Behavior<FrameworkElement> 
{ 
    protected override void OnAttached() 
    { 
     AssociatedObject.PreviewMouseUp += OpenContextMenu; 
    } 

    protected override void OnDetaching() 
    { 
     AssociatedObject.PreviewMouseUp -= OpenContextMenu; 
    } 

    void OpenContextMenu(object sender, MouseButtonEventArgs e) 
    { 
     if (e.ChangedButton == MouseButton.Left) { 
      FrameworkElement Sender = sender as FrameworkElement; 
      if (Sender != null) { 
       Sender.ContextMenu.PlacementTarget = Sender; 
       Sender.ContextMenu.IsOpen = true; 
       Sender.ContextMenu.UpdateLayout(); 
      } 
     } 
    } 
} 

Чтобы воспроизвести эту ошибку, просто нажмите быстро на различных клетках

+1

, пожалуйста, оставляйте код для Style 'DefaultContextMenuStyle' –

+0

@Massimil iano Kraus, есть только цвет фона –

+0

Пожалуйста, создайте [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve). –

ответ

0

Пересмотренный Ответ

После опубликовал полный, простой пример, я хотел бы предложить следующее: после создания ContextMenu

    Sender.ContextMenu.IsOpen = true; 
        Sender.ContextMenu.PreviewMouseUp += ContextMenu_PreviewMouseUp; 

Определив

private void ContextMenu_PreviewMouseUp(object sender, MouseButtonEventArgs e) 
    { 
     var Sender = (sender as ContextMenu); 
     if (Sender != null) 
     { 
      Sender.IsOpen = true; 
      e.Handled = true; 
     } 
    } 

(вы все еще должны управляйте выбором линии сетки, но это как без темы здесь)

+0

Нет, это не помогает. –

+0

@FrantsevM Пересмотренный. Попробуйте также с 'UpdateLayout' –

+0

И что * действительно * не помогает, так это то, что вы не делитесь полным примером и четкой, детерминированной последовательностью шагов для воспроизведения вашей проблемы. –

Смежные вопросы