2009-07-23 14 views
79

He configurado el elemento de mi WPF Datagrid en una lista de objetos devuelta desde mi DAL. También agregué una columna adicional que contiene un botón, la xaml está debajo.WPF DataGrid - Botón en una columna, obteniendo la fila de la que proviene el controlador de eventos Click

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

Esto rinde bien. Sin embargo, en el método Button_Click, ¿hay alguna forma de obtener la fila en la cuadrícula de datos donde reside el botón? Más específicamente, una de las propiedades de mis objetos es "Id", y me gustaría poder pasar esto al constructor de otro formulario en el controlador de eventos.

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

Tal vez necesito algo extra en mi xaml, o tal vez voy sobre esto de una manera indirecta? Cualquier ayuda/consejo apreciado.

Respuesta

103

Básicamente, su botón heredará el contexto de datos de un objeto de datos de fila. Lo llamo MyObject y espero que MyObject.ID sea lo que usted quería.

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

La forma ideal de hacer este tipo de cosas es usando comandos (básicamente el patrón MVVM) puede crear una coma nd en su objeto de datos (ViewModel) y llame a Button.Command, para que no haya ningún código detrás como Button haga clic. –

+3

¿puedes demostrar que haces eso con un comando? –

+1

@JobiJoy: ¿tiene un ejemplo de esto usando un Command/RelayCommand? Estoy intentando algunas cosas pero no puedo hacer que funcione ... – VoodooChild

35

Otra forma que me gusta hacer esto es para obligar a la ID de la propiedad CommandParameter del botón:

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

A continuación, se puede acceder a él como tal en código:

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

O puede usar una etiqueta para ello. – mans

+0

¿Por qué mezclan eventos y comandos? Use un Comando y use el parámetro de comando en él. – ProfK

+0

3 answers: ¿Por qué no? Sencillez. Y el OP pregunta por los controladores de eventos, no por los comandos. Un comando puede ser excesivo. El uso de 'CommandParameter' puede no ser el uso previsto de la propiedad, pero semánticamente, es más significativo que usar' Tag' y más simple que recuperar el ID del objeto enlazado en el controlador. Si prefiere los Comandos, ese enfoque está bien, pero ¿por qué agregar la complejidad si no va a usarlo? – xr280xr

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

Otra forma que se une al parámetro de comando DataContext y respeta MVVM como Jobi Joy dice que el botón hereda la fila de formulario de contexto de datos.

botón en XAML

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

aplicación Comando

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

     } 
    } 
+0

Entonces, ¿RowActionCommand estaría en el Modelo o restablecería el contexto de datos del botón al ViewModel? –

+0

RowActionCommand se define en cada modelo de vista de fila. –

+0

@ PetrŠebesta "RowActionCommand se define en cada modelo de vista de fila". Esto no tiene ningún sentido. Pero de todos modos, buena solución. – Igor

-1

Si su DataContext de cuadrícula de datos es un objeto DataView (la propiedad PresentaciónPredeterminada un DataTable), entonces usted puede también hacer esto:

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

Debería ser 'e.OriginalSource'. en lugar de 'e.Source'. – Bigeyes

+0

En serio Bigeyes, mi respuesta es de código real, en vivo, de trabajo! – SurfingSanta

Cuestiones relacionadas