2009-07-23 3 views
79

Ich habe die itemsource von meinem WPF Datagrid auf eine Liste von Objekten von meiner DAL zurückgegeben. Ich habe auch eine zusätzliche Spalte hinzugefügt, die eine Schaltfläche enthält, die XAML ist darunter.WPF DataGrid - Schaltfläche in einer Spalte, die Zeile, aus der es auf dem Click-Ereignishandler kam

<toolkit:DataGridTemplateColumn MinWidth="100" Header="View"> 
    <toolkit:DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <Button Click="Button_Click">View Details</Button> 
     </DataTemplate> 
    </toolkit:DataGridTemplateColumn.CellTemplate> 
</toolkit:DataGridTemplateColumn> 

Dies ist in Ordnung. Aber gibt es auf der Button_Click Methode, gibt es eine Möglichkeit, wie ich die Zeile auf dem Datagrid bekommen kann, wo sich die Schaltfläche befindet? Genauer gesagt, eine der Eigenschaften meiner Objekte ist "Id", und ich möchte in der Lage sein, dies in den Konstruktor eines anderen Formulars in der Ereignisbehandlungsroutine zu übergeben.

Vielleicht brauche ich etwas extra in meinem XAML, oder vielleicht mache ich das auf Umwegen? Jede Hilfe/Beratung geschätzt.

Antwort

103

Grundsätzlich erbt Ihre Schaltfläche den Datenkontext eines Zeilendatenobjekts. Ich nenne es als MyObject und hoffe, dass MyObject.ID das ist, was Sie wollten.

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    MyObject obj = ((FrameworkElement)sender).DataContext as MyObject; 
    //Do whatever you wanted to do with MyObject.ID 
} 
+6

Der ideale Weg, um diese Art von Sachen zu tun, ist die Verwendung von Befehlen (im Grunde MVVM-Muster) können Sie ein Komma erstellen nd in Ihrem Data Object (ViewModel) und rufen Sie Button.Command auf, damit kein Code wie Button klickt. –

+3

Können Sie das mit einem Befehl demonstrieren? –

+1

@JobiJoy: Haben Sie ein Beispiel dafür mit einem Command/RelayCommand? Ich versuche einige Dinge, aber ich kann es nicht zum Laufen bringen. – VoodooChild

35

Ein anderer Weg, Ich mag, dies zu tun ist, um die ID an die Commandparameter-Eigenschaft der Schaltfläche zu binden:

<Button Click="Button_Click" CommandParameter="{Binding Path=ID}">View Details</Button> 

Dann können Sie es wie so in Code zugreifen:

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    object ID = ((Button)sender).CommandParameter; 
} 
+0

Oder Sie können das Tag dafür verwenden. – mans

+0

Warum vermischen Sie Ereignisse und Befehle? Verwenden Sie einen Befehl und verwenden Sie den Befehlsparameter darin. – ProfK

+0

3 Antworten: Warum nicht? Einfachheit. Und das OP fragt nach Event-Handlern, nicht nach Befehlen. Ein Befehl könnte übertrieben sein. Die Verwendung von 'CommandParameter' ist möglicherweise nicht die beabsichtigte Verwendung der Eigenschaft, aber semantisch ist sie sinnvoller als die Verwendung von' Tag' und einfacher als das Abrufen der ID vom gebundenen Objekt im Handler. Wenn Sie Befehle bevorzugen, ist diese Vorgehensweise in Ordnung, aber warum sollten Sie die Komplexität hinzufügen, wenn Sie sie nicht verwenden wollen? – xr280xr

3
MyObject obj= (MyObject)((Button)e.Source).DataContext; 
9

Eine andere Möglichkeit, die an den Befehlsparameter DataContext gebunden wird und MVVM wie Jobi Joy respektiert, sagt, dass die Schaltfläche die Datenkontext-Formularzeile erbt.

Knopf in XAML

<RadButton Content="..." Command="{Binding RowActionCommand}" 
         CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext}"/> 

Befehl Implementierung

public void Execute(object parameter) 
    { 
     if (parameter is MyObject) 
     { 

     } 
    } 
+0

Wäre RowActionCommand also im Modell oder würden Sie den Datenkontext der Schaltfläche auf das ViewModel zurücksetzen? –

+0

RowActionCommand ist in jedem Zeilenansichtsmodell definiert. –

+0

@ PetrŠebesta "RowActionCommand ist in jedem Zeilenansichtsmodell definiert." Dies ergibt keinen Sinn. Aber trotzdem, nette Lösung. – Igor

-1

Wenn Ihr Datagrid Datacontext ein Dataview-Objekt (die Defaultview Eigenschaft eines Datatable), dann können Sie auch dies tun:

private void Button_Click(object sender, RoutedEventArgs e) { 
    DataRowView row = (DataRowView)((Button)e.Source).DataContext; 
} 
+0

Es sollte "e.Original Source" sein. anstelle von 'e.Quelle'. – Bigeyes

+0

Ernsthaft Bigeyes, meine Antwort stammt von echtem, funktionierendem Code! – SurfingSanta

Verwandte Themen