2012-02-28 16 views
7

Estoy tratando de recuperar información de fila de una cuadrícula de datos después de un evento de doble clic. Tengo la configuración del evento, pero ahora solo necesito configurar la función para recuperar los datos de la fila.Obtención de información de fila después de un doble clic

XAML:

<DataGrid 
     Width="Auto" 
     SelectionMode="Extended" 
     IsReadOnly="True" 
     Name="ListDataGrid" 
     AutoGenerateColumns="False" 
     ItemsSource="{Binding ListFieldObject.MoviesList}" 
     DataContext="{StaticResource MovieAppViewModel}" 
     cal:Message.Attach="[Event MouseDoubleClick] = [Action RowSelect()]"> 

     <DataGrid.Columns> 
      <DataGridTextColumn Width="200" IsReadOnly="True" Header="Title" Binding="{Binding Title}"/> 
      <DataGridTextColumn Width="100" IsReadOnly="True" Header="Rating" Binding="{Binding Rating}"/> 
      <DataGridTextColumn Width="100" IsReadOnly="True" Header="Stars" Binding="{Binding Stars}"/> 
      <DataGridTextColumn Width="93" IsReadOnly="True" Header="Release Year" Binding="{Binding ReleaseYear}"/> 
     </DataGrid.Columns> 
    </DataGrid> 

C# (MVVM modelo de vista):

 public void RowSelect() 
    { 
     //now how to access the selected row after the double click event? 
    } 

Gracias tanto!

+0

De lo que puedo decir que es muy difícil, si no imposible. Muchos sitios web discuten esto, p. http://www.scottlogic.co.uk/blog/colin/2008/12/wpf-datagrid-detection-clicked-cell-and-row/y este http://stackoverflow.com/questions/5808616/how-to-bind-a-command-to- double-click-on-a-row-in-datagrid – Phil

Respuesta

6

Con Caliburn Es muy fácil, sólo tiene que pasar $ DataContext en su XAML:

cal:Message.Attach="[Event MouseDoubleClick] = [Action RowSelect($dataContext)]"> 

Y cambiar su método a:

public void RowSelect(MoviesListItem movie) 
{ 
    //now how to access the selected row after the double click event? 
} 

// EDITAR Lo sentimos, la solución anterior sólo funcionará si la acción está en la misma DataTemplate ... otra solución sería tener un aprieto SelectedItem y sólo lo utilizan en su método:

<DataGrid 
    SelectedItem="{Binding SelectedMovie,Mode=TwoWay}" 
    cal:Message.Attach="[Event MouseDoubleClick] = [Action RowSelect()]"> 

y en su código:

public void RowSelect() 
{ 
    //SelectedMovie is the item where the user double-cliked 
} 
+0

Así es como terminé haciéndolo. ¡Gracias por la ayuda! – Josh

+0

Esta solución es viable, pero por experiencia, tiene el inconveniente de tener un comportamiento impredecible si el usuario está haciendo clic rápidamente en las áreas de su cuadrícula de datos. El ejemplo más notable: al usuario le gusta hacer clic rápidamente en la flecha hacia abajo o en la barra de desplazamiento vertical en la barra de desplazamiento vertical si se desplazan por una lista grande. Muchos usuarios no hacen clic y arrastran el control para desplazarse; en cambio, martillean la flecha o la trayectoria del pulgar. Esta solución provocará que el doble clic se ejecute invariablemente, ya que es manejado por la cuadrícula de datos y no por la fila de datos. – Adrian

+0

@Josh, esta solución también manejará clics dobles en los encabezados de columna, que apenas es necesario. Para evitar esto, considere la solución de * David Kiff * abajo. – Sevenate

1

(esperan que ayude a) No estoy seguro acerca de su caso, pero esto es lo que hago en Windows Forms:

  int index = dataGridView2.CurrentRow.Index; //determine which item is selected 
      textBox8.Text = dataGridView2.Rows[index].Cells[0].Value.ToString(); //add login 
+0

se ingresa se aprecia pero estoy usando el patrón MVVM y no puedo tener las llamadas en el código detrás. Editaré la publicación original para reflejar el hecho de que C# está en ViewModel. – Josh

1

Puede hacerlo modificando la plantilla de control para los DataGridRows expuestos por DataGrid. El siguiente ejemplo usa WPF y el tema Aero.

Lo único que he hecho es eliminar tu cal anterior: Message.Attach llama y lo mueve a un nuevo ContentControl de "marcador de posición" que rodea el borde (x: Name = DGR_Border) en la plantilla de control "predeterminada". (I utilizado ContentControl porque no tiene elementos visuales de su propia y se expone a un evento MouseDoubleClick.)

<DataGrid Width="Auto" 
      SelectionMode="Extended" 
      IsReadOnly="True" 
      Name="ListDataGrid" 
      AutoGenerateColumns="False" 
      ItemsSource="{Binding ListFieldObject.MoviesList}" 
      DataContext="{StaticResource MovieAppViewModel}"> 

    <DataGrid.Columns> 
     <DataGridTextColumn Width="200" IsReadOnly="True" Header="Title" Binding="{Binding Title}"/> 
     <DataGridTextColumn Width="100" IsReadOnly="True" Header="Rating" Binding="{Binding Rating}"/> 
     <DataGridTextColumn Width="100" IsReadOnly="True" Header="Stars" Binding="{Binding Stars}"/> 
     <DataGridTextColumn Width="93" IsReadOnly="True" Header="Release Year" Binding="{Binding ReleaseYear}"/> 
    </DataGrid.Columns> 
    <DataGrid.RowStyle> 
     <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> 
     <Setter Property="SnapsToDevicePixels" Value="true"/> 
     <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/> 
     <Setter Property="ValidationErrorTemplate"> 
      <Setter.Value> 
       <ControlTemplate> 
        <TextBlock Foreground="Red" Margin="2,0,0,0" Text="!" VerticalAlignment="Center"/> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
      <Setter.Value>          
       <ControlTemplate TargetType="{x:Type DataGridRow}"> 
        <ContentControl cal:Message.Attach="[Event MouseDoubleClick] = [Action RowSelect($datacontext)]"> 
         <Border x:Name="DGR_Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> 
          <SelectiveScrollingGrid> 
           <SelectiveScrollingGrid.ColumnDefinitions> 
            <ColumnDefinition Width="Auto"/> 
            <ColumnDefinition Width="*"/> 
           </SelectiveScrollingGrid.ColumnDefinitions> 
           <SelectiveScrollingGrid.RowDefinitions> 
            <RowDefinition Height="*"/> 
            <RowDefinition Height="Auto"/> 
           </SelectiveScrollingGrid.RowDefinitions> 
           <DataGridCellsPresenter Grid.Column="1" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
           <DataGridDetailsPresenter Grid.Column="1" Grid.Row="1" SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Visibility="{TemplateBinding DetailsVisibility}"/> 
           <DataGridRowHeader Grid.RowSpan="2" SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Row}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/> 
          </SelectiveScrollingGrid> 
         </Border> 
        </ContentControl> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </DataGrid.RowStyle> 
</DataGrid> 

La única otra cosa que usted tiene que hacer es modificar su método de RowSelect() para aceptar un parámetro de lo tipo que estás usando aquí (solo asumí que era del tipo 'Película').

public void RowSelect(Movie movie) 
{ 
    // do something with 'movie' 
} 
0

Mi ejemplo hay una columna con NAME "service_id". Pero también puedes usar el desplazamiento de columna int32. Incluso hay un ItemArray en DataRowView TYPE para ejecutar y hacia abajo. Consulte el espacio de nombre System.Data. El origen/contexto de elementos de la cuadrícula de datos afectará a los "objetos" que ve dentro de la cuadrícula de datos. Pero si ingresa los tipos de depuración, puede enviarlos y usarlos.

private void DataGridServiceRegistry_MouseDoubleClick(object sender, MouseButtonEventArgs e) 
{ 
    DataGrid DGSR = (DataGrid) sender; 
    var SR = (DataRowView) DGSR.CurrentItem; 
    var service_id = SR.Row["SERVICE_ID"]; 
} 
17

Usted puede hacer esto, alternativamente:

<DataGrid> 
    <DataGrid.RowStyle> 
     <Style TargetType="DataGridRow"> 
      <Setter Property="cal:Message.Attach" Value="[MouseDoubleClick] = [Action RowSelect($dataContext)]"/> 
     </Style> 
    </DataGrid.RowStyle> 
</DataGrid> 

Entonces

public void RowSelect(MoviesListItem movie) 
{ 
    //now how to access the selected row after the double click event? 
} 
+2

Esta solución es mucho mejor que la respuesta aceptada, ya que solo captura dos clics en las filas, pero no en los encabezados. – Sevenate

+1

Esta es la respuesta que he estado buscando y debería marcarse como la respuesta. –

Cuestiones relacionadas