2016-08-31 2 views
0

Ich habe einen Fehler gefunden, und ich verstehe nicht, warum es passiert. Ich habe DataGrid. Mit der linken Maustaste klicken Ich möchte ContextMenu öffnen. Ich habe es geschafft. Es funktioniert gut, bis ich anfange, auf DataGrids Zellen zufällig zu klicken (jedes Mal, wenn ContextMenu schließt und wieder an einem neuen Ort erscheint). Aber in einem Moment passiert etwas und ContextMenu neueres Erscheinen (und Fenster reagieren nicht auf irgendwelche Mausereignisse wie das Klicken auf Knöpfe und so weiter) ... bis ich Cursor aus Fenster heraus bewege und es zurückbringe (oder klick auf Alt oder F10) .WPF ContextMenu Schlucken aller Mausereignisse

Hier einige Code:
ContextMenu (innen <DataGrid.Resources>)

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

Datagrid-Spalte:

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

Und Verhalten ContextMenu öffnen:

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; 
     } 
    } 
} 

Als ich diesen Fehler gefunden Ich habe versucht, ein paar Infos mit Snoop zu finden WPF. Und hier ein paar Informationen von ihm:

  1. Bevor schlechte Sache, klicken Sie auf Zelle passiert war wie:
    before bad thing

  2. Nach Schlimme:
    after bad thing
    Erste Veranstaltung im Popup passiert (ContextMenu Teil?), es gehört nicht zum Fenster VisualTree. Dieses Popup scheint sich über das gesamte Hauptfenster zu erstrecken und zu schließen, wenn ich die Maus aus dem Fenster schiebe.

So verlor ich 2 Tage auf dem Fehler und das ist alles, das ich finden kann.
Bitte helfen Sie mir.

EDIT: ich minimal Beispiel erstellt:

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> 

-Code hinter:

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(); 
      } 
     } 
    } 
} 

diesen Fehler zu reproduzieren nur schnell klicken auf verschiedenen Zellen

+1

Bitte schreiben Sie den Code für den Style 'DefaultContextMenuStyle' –

+0

@Massimil iano Kraus, es gibt nur Hintergrundfarbe –

+0

Bitte erstellen Sie ein [Minimal, Complete und Verifable Beispiel] (http://stackoverflow.com/help/mcve). –

Antwort

0

Überarbeitete Antwort

Nachdem Sie ein vollständiges, einfaches Beispiel veröffentlicht, würde ich vorschlagen, die folgenden: , nachdem Sie die ContextMenu

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

Nachdem definiert

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

(Sie noch erstellen müssen Verwalten Sie die Gitterlinienauswahl, aber es ist wie off topic hier)

+0

Nein, es hilft nicht. –

+0

@FrantsevM Überarbeitet. Versuchen Sie auch mit 'UpdateLayout' –

+0

Und was * wirklich * nicht hilft, ist, dass Sie nicht ein vollständiges Beispiel und eine klare, deterministische Abfolge von Schritten teilen, um Ihr Problem zu reproduzieren. –