2011-03-04 8 views
6

Tengo un WPF Datagrid enganchan a algunas propiedades en mi modelo de vistaWPF cuadrícula de datos: En la carga, la selección de elemento actual (destacando)

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

Cuando mi carga de la ventana y la cuadrícula de datos también, que establecen 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 SelectedItem en el DataGrid durante la carga/inicialización?

EDIT:

De hecho, es seleccionada porque tengo la pequeña celda de selección. Es solo la prestación de la Resaltación lo que no se dispara.

enter image description here

Respuesta

7

Cuando se utiliza un modelo como el DataContext para una ventana de WPF, el evento de la cuadrícula de datos SelectionChanged no se consiga llamar hasta después de la ventana se carga por lo que la fila no se destacó y sólo se ve la primera fila con el resaltado parcial. Puede haber una manera más elegante, pero aquí hay una solución alternativa.

En caso de carga de la ventana o evento cargado de la cuadrícula de datos, restablecer la unión 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; 
    } 
} 

He aquí una muestra de trabajo completo.

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; 
     } 
    } 
} 
+0

No hay evento '' Loaded' en UIElement' –

+1

'' DataGrid' hereda de Controls' el cual tiene un evento 'Loaded': [MSDN DataGrid Eventos] (http: // msdn.microsoft.com/en-us/library/system.windows.controls.datagrid_events.aspx) –

+0

@Smurf - restableciendo SelecteItem ha resuelto un problema que he intentado comprender durante un par de días. ¡¡¡Gracias!!! – GilShalit

6

que tenía el mismo "problema" y finalmente encontré una muy buena solución 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.

Así que 2 opciones;

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

Para ello, 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 que ayude!

Saludos, LTB

0

Esto es un poco de un viejo, pero ninguna de las respuestas en cualquier puesto parece conseguirlo del todo 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, por lo que todo funciona. Una molestia adicional proviene del hecho de que son las células que quedan resaltadas, no las filas, por lo que básicamente necesita para duplicar el estilo de resaltado celular:

<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> 

cuenta que hay un gotcha, que para establecer el contexto de la fila menú que necesita para reemplazar el estilo DataGridRow en el DataGrid, por lo que si hace esto globalmente y no funciona, verifique que su RowStyle no haya sido anulado.

0

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).

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

enter image description here

//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); 
Cuestiones relacionadas