When using a Model as the DataContext for a WPF Window, the DataGrid's SelectionChanged
event doesn't get called until after the Window is loaded which is why the row is never highlighted and you only see the first row with the partial highlight. There may be a more elegant way, but here's a work-around.
In the Window's loaded event or the DataGrid's loaded event, reset the SelectedItem binding:
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;
}
}
Here's a complete working sample.
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>
Code Behind
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;
}
}
}
Loaded
event onUIElement
– Leafstalk