it-swarm.com.de

WPF-Datengitter-Kontextmenü aufrufen Klicken Sie auf Zeile

Ich habe ein WPF-DataGrid

<DataGrid AutoGenerateColumns="False"  Name="dataGrid1"  IsReadOnly="True" >
<DataGrid.Columns>
    <DataGridTextColumn Header="Site" Binding="{Binding Site}" Width="150" />
    <DataGridTextColumn Header="Subject" Binding="{Binding Subject}" Width="310" />
</DataGrid.Columns>
<DataGrid.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Delete" Click="Context_Delete">
            <MenuItem.Icon>
                <Image Width="12" Height="12" Source="Images/Delete.png" />
            </MenuItem.Icon>
        </MenuItem>
    </ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>

Ich habe den Click-Event-Handler als: 

private void Context_Delete(object sender, System.EventArgs e)  { }

Wie erhalte ich die Zeile, in der sich das Kontextmenü vor dem Klick befunden hat? Das sender-Objekt ist System.Windows.Controls.MenuItem, nicht das DataGridRow. Woher bekomme ich die DataGridRow, wo das Kontextmenü angeklickt wurde? (Ich setze den DataGrid.ItemSource in den Code hinter der Datei.)

16
O.O.

Ich gehe also davon aus, dass Sie, basierend auf Ihrem Beispielcode, Ihr DataGrid an eine ObservableCollection von Objekten binden, deren Eigenschaften Sie Site und Subject an die DataGridColumns binden.

Im Wesentlichen müssen Sie nur herausfinden, was das an die angeklickte DataGridRow gebundene Element ist, und es aus Ihrer ObservableCollection entfernen. Hier ist ein Beispielcode für den Einstieg:

private void Context_Delete(object sender, RoutedEventArgs e)
{
    //Get the clicked MenuItem
    var menuItem = (MenuItem)sender;

    //Get the ContextMenu to which the menuItem belongs
    var contextMenu = (ContextMenu)menuItem.Parent;

    //Find the placementTarget
    var item = (DataGrid)contextMenu.PlacementTarget;

    //Get the underlying item, that you cast to your object that is bound
    //to the DataGrid (and has subject and state as property)
    var toDeleteFromBindedList = (YourObject)item.SelectedCells[0].Item;

    //Remove the toDeleteFromBindedList object from your ObservableCollection
    yourObservableCollection.Remove(toDeleteFromBindedList);
}
27
dsfgsho

Normalerweise beschäftigen Sie sich nicht mit Zeilen (wenn Sie dies tun - denken Sie noch einmal über die Gründe nach) - Sie arbeiten stattdessen mit dem Ansichtsmodell. Wenn Sie das Kontextmenü öffnen, wird Ihr Element ausgewählt, sodass Sie über die DataGrid.SelectedItem-Eigenschaft darauf zugreifen können. Wenn Sie jedoch wirklich DataGridRow benötigen, haben Sie DataGrid.SelectedIndex, und auf SO finden Sie viele Antworten, wie Sie die Zeile erhalten. Like Holen Sie sich eine Zeile in Datagrid

6
morincer

Um den oben genannten Punkt von Morincer mit einem Beispiel zu erweitern, endete ich mit einem einfacheren Ansatz ...

 private void MenuItem_OnClickRemoveSource(object sender, RoutedEventArgs e)
 {
     if (SourceDataGrid.SelectedItem == null) return;  //safety first

     _importViewModel.SourceList.Remove((SourceFileInfo)SourceDataGrid.SelectedItem);
 }

In meinem Fall das

_importViewModel.SourceList 

ist die ObservableCollection, an die die Zeilen gebunden sind. Gemäß den bewährten Methoden entferne ich einfach das ausgewählte Element aus der Sammlung, und die Bindung übernimmt die Benutzeroberfläche. 

3
ebol2000

die Antwort von dsfgsho funktionierte für mich, aber ein Rechtsklick auf eine Rasterzeile wählt sie nicht automatisch aus. Das bedeutet, wenn Ihr Fokus an einer anderen Stelle liegt und Sie mit der rechten Maustaste einen Kontextmenüeintrag auswählen und auswählen, können Sie eine Ausnahmebedingung für item.electedCells [0] erhalten, oder Sie haben eine Zeile ausgewählt und klicken mit der rechten Maustaste auf eine andere Zeile erhalten Sie möglicherweise unerwartete Ergebnisse.

Ich behandelte dies, indem ich "PreviewMouseRightButtonDown" auf dem Datagrid behandelte. Hier wähle ich explizit eine Zeile aus, wenn sie mit der rechten Maustaste angeklickt wird. Ich habe vergessen, woher meine UIHelpers-Klasse stammt (wahrscheinlich an anderer Stelle auf dieser Website - ich habe sie zum Auflösen von Drag & Drop-Elementen verwendet), aber dies sollte Sie in die richtige Richtung weisen, wenn Sie auf dieses Problem stoßen. Dies ist eine Erweiterung der akzeptierten Antwort:

// handle right mouse click to select the correct item for context menu usage
    private void myDataGrid_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        //find the clicked row
        DataGridRow row = UIHelpers.TryFindFromPoint<DataGridRow>((UIElement) sender, e.GetPosition(myDataGrid));
        if (row == null)
        {
            Debug.WriteLine("Row is null");
            return;
        }
        else
        {
            Debug.WriteLine("Grid Row Index is " + row.GetIndex().ToString());
            (sender as DataGrid).SelectedIndex = row.GetIndex();
        }
    }
2
Elemental Pete

UIHelper von Elemental Pete stammt wahrscheinlich von:

http://www.hardcodet.net/2009/03/moving-data-grid-rows-using-drag-and-drop -

Dieser Artikel listet eine Zip-Datei auf, die UIHelper.cs enthält. Es ist nicht mein Code, also kein Kopieren/Einfügen hier.

0
Patrick Artner