WPF Datagrid establece una fila seleccionada

¿Cómo utilizo Datagrid.SelectedItem para seleccionar una fila programáticamente?

¿Tengo que crear IEnumerable un objeto IEnumerable of DataGridRow y pasar la fila correspondiente a esta propiedad SelectedItem o cómo lo hago?

EDITAR:

Necesito hacer coincidir el contenido de la celda de la primera columna con TextBox.Text primero, antes de seleccionar la fila.

por favor verifique si el código a continuación funcionaría para usted; itera a través de las celdas de la primera columna de Datagris y comprueba si el contenido de la celda es igual al valor textbox.text y selecciona la fila.

 for (int i = 0; i < dataGrid.Items.Count; i++) { DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(i); TextBlock cellContent = dataGrid.Columns[0].GetCellContent(row) as TextBlock; if (cellContent != null && cellContent.Text.Equals(textBox1.Text)) { object item = dataGrid.Items[i]; dataGrid.SelectedItem = item; dataGrid.ScrollIntoView(item); row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); break; } } 

espero que esto ayude, saludos

No necesita iterar a través de las filas de DataGrid , puede lograr su objective con una solución más simple. Para hacer coincidir su fila, puede iterar a través de su colección que estaba vinculada a su propiedad DataGrid.ItemsSource y luego asignarle este elemento a la propiedad DataGrid.SelectedItem progtwigción, alternativamente puede agregarlo a su colección DataGrid.SelectedItems si desea permitir el usuario para seleccionar más de una fila. Vea el código a continuación:

       

 public partial class MainWindow : Window { public class Employee { public string Code { get; set; } public string Name { get; set; } } private ObservableCollection _empCollection; public MainWindow() { InitializeComponent(); } private void OnWindowLoaded(object sender, RoutedEventArgs e) { // Generate test data _empCollection = new ObservableCollection { new Employee {Code = "E001", Name = "Mohammed A. Fadil"}, new Employee {Code = "E013", Name = "Ahmed Yousif"}, new Employee {Code = "E431", Name = "Jasmin Kamal"}, }; /* Set the Window.DataContext, alternatively you can set your * DataGrid DataContext property to the employees collection. * on the other hand, you you have to bind your DataGrid * DataContext property to the DataContext (see the XAML code) */ DataContext = _empCollection; } private void OnSelectionButtonClick(object sender, RoutedEventArgs e) { /* select the employee that his name matches the * name on the TextBox */ var emp = (from i in _empCollection where i.Name == empNameTextBox.Text.Trim() select i).FirstOrDefault(); /* Now, to set the selected item on the DataGrid you just need * assign the matched employee to your DataGrid SeletedItem * property, alternatively you can add it to your DataGrid * SelectedItems collection if you want to allow the user * to select more than one row, eg: * empDataGrid.SelectedItems.Add(emp); */ if (emp != null) empDataGrid.SelectedItem = emp; } } 

Es un poco más complicado hacer lo que intentas hacer de lo que preferiría, pero eso se debe a que realmente no vinculas directamente un DataGrid a un DataTable .

Cuando vincula DataGrid.ItemsSource a un DataTable , realmente lo vincula al DataView predeterminado, no a la tabla misma. Esta es la razón por la que, por ejemplo, no es necesario hacer nada para hacer que DataGrid ordene filas al hacer clic en el encabezado de una columna: esa funcionalidad está integrada en DataView y DataGrid sabe cómo acceder a ella (a través de la interfaz IBindingList ).

El DataView implementa IEnumerable (más o menos), y DataGrid llena sus elementos iterando sobre esto. Esto significa que cuando haya vinculado DataGrid.ItemsSource a un DataTable , su propiedad SelectedItem será un DataRowView , no un DataRow .

Si sabes todo esto, es bastante sencillo crear una clase contenedora que te permita exponer las propiedades a las que puedes vincular. Hay tres propiedades clave:

  • Table , la DataTable ,
  • Row , una propiedad DataRowView del tipo DataRowView , y
  • SearchText , una propiedad de cadena que, cuando esté configurada, encontrará el primer DataRowView coincidente en la vista predeterminada de la tabla, establecerá la propiedad Row y levantará PropertyChanged .

Se parece a esto:

 public class DataTableWrapper : INotifyPropertyChanged { private DataRowView _Row; private string _SearchText; public DataTableWrapper() { // using a parameterless constructor lets you create it directly in XAML DataTable t = new DataTable(); t.Columns.Add("id", typeof (int)); t.Columns.Add("text", typeof (string)); // let's acquire some sample data t.Rows.Add(new object[] { 1, "Tower"}); t.Rows.Add(new object[] { 2, "Luxor" }); t.Rows.Add(new object[] { 3, "American" }); t.Rows.Add(new object[] { 4, "Festival" }); t.Rows.Add(new object[] { 5, "Worldwide" }); t.Rows.Add(new object[] { 6, "Continental" }); t.Rows.Add(new object[] { 7, "Imperial" }); Table = t; } // you should have this defined as a code snippet if you work with WPF private void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler h = PropertyChanged; if (h != null) { h(this, new PropertyChangedEventArgs(propertyName)); } } public event PropertyChangedEventHandler PropertyChanged; // SelectedItem gets bound to this two-way public DataRowView Row { get { return _Row; } set { if (_Row != value) { _Row = value; OnPropertyChanged("Row"); } } } // the search TextBox is bound two-way to this public string SearchText { get { return _SearchText; } set { if (_SearchText != value) { _SearchText = value; Row = Table.DefaultView.OfType() .Where(x => x.Row.Field("text").Contains(_SearchText)) .FirstOrDefault(); } } } public DataTable Table { get; private set; } } 

Y aquí está XAML que lo usa:

                 

He buscado una solución a un problema similar y tal vez mi camino te ayudará a ti y a cualquier persona que se enfrente a ella.

Utilicé SelectedValuePath="id" en la definición de XAML DataGrid, y lo único programtico que tengo que hacer es establecer DataGrid.SelectedValue en el valor deseado.

Sé que esta solución tiene ventajas y desventajas, pero en casos específicos es rápida y fácil.

Atentamente

Marcin

// En general, para acceder a todas las filas //

 foreach (var item in dataGrid1.Items) { string str = ((DataRowView)dataGrid1.Items[1]).Row["ColumnName"].ToString(); } 

// Para acceder a las filas seleccionadas //

 private void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e) { try { string str = ((DataRowView)dataGrid1.SelectedItem).Row["ColumnName"].ToString(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } 

Cambié el código de serge_gubenko y funciona mejor

 for (int i = 0; i < dataGrid.Items.Count; i++) { string txt = searchTxt.Text; dataGrid.ScrollIntoView(dataGrid.Items[i]); DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(i); TextBlock cellContent = dataGrid.Columns[1].GetCellContent(row) as TextBlock; if (cellContent != null && cellContent.Text.ToLower().Equals(txt.ToLower())) { object item = dataGrid.Items[i]; dataGrid.SelectedItem = item; dataGrid.ScrollIntoView(item); row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); break; } } 

Me encontré con este artículo de TechNet bastante reciente (en comparación con la edad de la pregunta) que incluye algunas de las mejores técnicas que pude encontrar sobre el tema:

WPF: Seleccionar y centrar mediante progtwigción una fila o celda en un DataGrid

Incluye detalles que deberían cubrir la mayoría de los requisitos. Es importante recordar que si especifica plantillas personalizadas para DataGridRow para algunas filas, estas no tendrán DataGridCells dentro y entonces los mecanismos de selección normales de la grilla no funcionarán.

Tendrá que ser más específico sobre qué fuente de datos le ha dado a la grilla para responder la primera parte de su pregunta, como han dicho los otros.

Si alguien tropieza aquí tiene problemas con la selección de la grilla interna que ocurre después de OnSelectionChanged: después de probar infructuosamente todos los selectores de selección durante una docena de horas, lo único que funcionó para mí fue volver a cargar y repoblar DataGrid junto con el elemento seleccionado. No es nada elegante, pero en este momento no estoy seguro de si existe una mejor solución en mi situación.

 datagrid.ItemsSource = null datagrid.ItemsSource = items; datagrid.SelectedItem = selectedItem;