2009-07-23 13 views
79

Ho impostato l'origine elementi del mio Datagrid WPF in un elenco di oggetti restituiti dal mio DAL. Ho anche aggiunto una colonna in più che contiene un pulsante, la xaml è sotto.DataGrid WPF - Pulsante in una colonna, ottenendo la riga da cui proviene il gestore eventi Click

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

Questo rende bene. Tuttavia sul metodo Button_Click, c'è un modo per ottenere la riga sul datagrid in cui risiede il pulsante? Più in particolare, una delle proprietà dei miei oggetti è "Id", e mi piacerebbe poterlo trasferire nel costruttore di un altro modulo nel gestore di eventi.

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     //I need to know which row this button is on so I can retrieve the "id" 
    } 

Forse ho bisogno di qualcosa in più nel mio XAML, o forse ho intenzione di questo in modo indiretto? Qualsiasi aiuto/consiglio apprezzato.

risposta

103

Fondamentalmente il pulsante erediterà il datacontext di un oggetto dati riga. Lo chiamo come MyObject e spero che MyObject.ID sia quello che volevi.

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

Il modo ideale per fare questo genere di cose è usare i comandi (in pratica pattern MVVM) è possibile creare una virgola nd nel tuo oggetto dati (ViewModel) e chiama Button.Command, in modo che non ci sia alcun codice dietro come Button clic. –

+3

puoi dimostrarlo facendo un comando? –

+1

@JobiJoy: ne hai un esempio utilizzando un comando/RelayCommand? Sto provando poche cose ma non riesco a farlo funzionare .. – VoodooChild

35

Un altro modo in cui mi piace fare questo è di impegnare la ID alla proprietà CommandParameter del pulsante:

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

Quindi è possibile accedere in questo modo in codice:

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

Oppure puoi usare un tag per questo. – mans

+0

Perché stai mescolando eventi e comandi? Utilizzare un comando e utilizzare il parametro di comando in esso. – ProfK

+0

3 risposte: perché no? Semplicità. E l'OP chiede di gestori di eventi, non di comandi. Un comando potrebbe essere eccessivo. L'uso di 'CommandParameter' potrebbe non essere l'uso previsto della proprietà, ma semanticamente, è più significativo dell'uso di' Tag' e più semplice del recupero dell'ID dall'oggetto associato nel gestore. Se preferisci i Comandi, questo approccio va bene, ma perché aggiungere la complessità se non la userai? – xr280xr

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

Un altro modo che si associa al parametro DataContext e che rispetta MVVM come Gioia Gioia dice che il pulsante eredita la riga del modulo datacontext.

Button in XAML

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

implementazione dei comandi

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

     } 
    } 
+0

Quindi RowActionCommand dovrebbe essere nel modello o si ripristinerebbe il datacontext del pulsante sul ViewModel? –

+0

RowActionCommand è definito in ogni modello di vista di riga. –

+0

@ PetrŠebesta "RowActionCommand è definito in ogni modello di vista riga." Questo non ha alcun senso. Ma comunque, bella soluzione. – Igor

-1

Se il DataContext di DataGrid è un oggetto DataView (la proprietà predefinita di un DataTable), allora si può anche fare questo:

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

Dovrebbe essere "e.originale fonte". invece di 'e.Source'. – Bigeyes

+0

Scherzi a parte, la mia risposta è da codice reale, dal vivo e funzionante! – SurfingSanta

Problemi correlati