wpf datagrid initialization selection highlighting

WPF Datagrid: En carga, selección en el elemento actual(resaltado)



initialization selection (4)

Tengo un WPF Datagrid vinculado a algunas propiedades en mi ViewModel

<DataGrid AutoGenerateColumns="False" Name="dataGrid" SelectionMode="Single" ItemsSource="{Binding ItemList}" SelectedItem="{Binding SelectedItem}"> ... </DataGrid>

Cuando mi ventana se carga y Datagrid también, configuro el SelectedItem y se une bien, pero la fila no está resaltada. En el momento en que hago clic en una fila, se resalta la fila y se resuelve el problema.

¿Cómo puedo configurar / activar el resaltado del elemento SelectedItem en DataGrid durante la carga / inicialización?

EDITAR:

En realidad está seleccionado porque tengo la pequeña celda de selección. Es solo la prestación de la Resaltación lo que no se dispara.


Cuando se utiliza un modelo como DataContext para una ventana de WPF, el evento SelectionChanged de DataGrid no se llama hasta que se carga la ventana, por lo que la fila nunca se resalta y solo se ve la primera fila con el resaltado parcial. Puede haber una manera más elegante, pero aquí hay una solución alternativa.

En el evento cargado de la ventana o en el evento cargado de DataGrid, restablezca el enlace SelectedItem:

public MainWindow() { InitializeComponent(); this.Loaded += new RoutedEventHandler( OnLoaded ); } // could also be placed in the DataGrid''s loaded event handler private void OnLoaded( object sender, RoutedEventArgs e ) { if( dataGrid != null && Model.SelectedItem != null ) { var selected = Model.SelectedItem; Model.SelectedItem = null; Model.SelectedItem = selected; } }

Aquí hay una muestra completa de trabajo.

XAML

<Window x:Class="WpfDataGridHighlightOnLoad.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:model="clr-namespace:WpfDataGridHighlightOnLoad" Title="MainWindow" Height="350" Width="525"> <Window.DataContext> <model:MainWindowModel x:Name="Model" /> </Window.DataContext> <Grid> <DataGrid AutoGenerateColumns="True" SelectionMode="Single" HorizontalAlignment="Stretch" Name="dataGrid" VerticalAlignment="Top" ItemsSource="{Binding ItemList}" SelectedItem="{Binding SelectedItem}"> </DataGrid> <Button Content="Cycle Selection" Click="OnCycleClick" Height="23" HorizontalAlignment="Right" Name="button1" VerticalAlignment="Bottom" Width="125" /> <Button Content="Reset Grid" Click="OnResetClick" Height="23" HorizontalAlignment="Left" Name="button2" VerticalAlignment="Bottom" Width="125" /> </Grid> </Window>

Código detrás

using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows; namespace WpfDataGridHighlightOnLoad { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.Loaded += new RoutedEventHandler( OnLoaded ); } // could also be placed in the DataGrid''s loaded event handler private void OnLoaded( object sender, RoutedEventArgs e ) { if( dataGrid != null && Model.SelectedItem != null ) { var selected = Model.SelectedItem; Model.SelectedItem = null; Model.SelectedItem = selected; } } private void OnCycleClick( object sender, RoutedEventArgs e ) { int index = Model.ItemList.IndexOf( Model.SelectedItem ); index = index == Model.ItemList.Count - 1 ? 0 : index + 1; Model.SelectedItem = Model.ItemList[index]; } private void OnResetClick( object sender, RoutedEventArgs e ) { Model.Reset(); } } public class MainWindowModel : INotifyPropertyChanged { public MainWindowModel() { Reset(); } public void Reset() { ItemList = new List<Person> { new Person("Joe", 20), new Person("John", 30), new Person("Jane", 40), new Person("Jill", 50), new Person("Fido", 7), }; SelectedItem = ItemList[2]; } private Person _selectedItem; public Person SelectedItem { get { return _selectedItem; } set { _selectedItem = value; NotifyPropertyChanged( "SelectedItem" ); } } private List<Person> _itemList; public List<Person> ItemList { get { return _itemList; } set { _itemList = value; NotifyPropertyChanged( "ItemList" ); } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged( String info ) { if( PropertyChanged != null ) { PropertyChanged( this, new PropertyChangedEventArgs( info ) ); } } #endregion } public class Person { public string Name { get; set; } public int Age { get; set; } public Person( string name, int age ) { Name = name; Age = age; } public override string ToString() { return Name; } } }


Este es un poco antiguo, pero ninguna de las respuestas en una publicación parece estar bien. Lo que quiere es que funcione de la manera en que debería funcionar: es decir, el resaltado es el mismo independientemente de que el control haya tenido foco alguna vez (lo que parece ser algo incidental).

Esto se puede hacer con un estilo DataGridRow , pero el truco no es especificar los colores por ti mismo, sino usar los colores predeterminados, para que todo funcione. Una molestia adicional proviene del hecho de que son las celdas las que se resaltan, no las filas, por lo que básicamente se necesita duplicar el estilo de resaltado de la celda:

<Style x:Key="DataGridRowStyle" TargetType="{x:Type DataGridRow}"> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsKeyboardFocusWithin" Value="False" /> <Condition Property="IsSelected" Value="True" /> </MultiTrigger.Conditions> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}" /> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}" /> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsKeyboardFocusWithin" Value="True" /> <Condition Property="IsSelected" Value="True" /> </MultiTrigger.Conditions> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" /> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" /> </MultiTrigger> </Style.Triggers> </Style>

Tenga en cuenta que hay un error, que para establecer el menú contextual de la fila debe sobrescribir el estilo DataGridRow en DataGrid , por lo tanto, si hace esto globalmente y no funciona, verifique que su RowStyle no haya sido anulado.


Se encontró con el mismo problema al insertar datos ficticios en un WGD DataGrid, y luego tratar de alterar el orden de las filas. La hightlighting de fila bunked hacia fuera (imagen abajo).

Porque estaba insertando el mismo objeto de registro "mismo" varias veces.

//Ex: Messes up highlighting. grid.Items.Add(rowObj); grid.Items.Add(rowObj); grid.Items.Add(rowObj); //Ex: Highlighting OK. Create a new object each time. Even if all columns have exact same values. rowobj = new ..... grid.Items.Add(rowObj); rowobj = new ..... grid.Items.Add(rowObj);


Tuve el mismo "problema" y finalmente encontré una solución bastante buena para el problema. Como ya dijiste, no es que la fila no esté seleccionada, sino que no resalta la fila. Si observa cuidadosamente, notará que al hacer clic en cualquier lugar de la fila (usando el mouse), aún no resalta la fila, solo las celdas dentro de ella.

Entonces 2 opciones;

  • Crear código para seleccionar las celdas de la fila
  • o crea un Style.Trigger para resaltar la fila (que es la mejor opción en mi mente).

Para hacer esto, agregue algo como esto a la cuadrícula de datos en el archivo xaml:

<DataGrid.RowStyle> <Style TargetType="DataGridRow"> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="DodgerBlue"/> <Setter Property="Foreground" Value="White"/> </Trigger> </Style.Triggers> </Style> </DataGrid.RowStyle>

¡Espero eso ayude!

Saludos, LTB