I’ve got a WPF DataGrid that I have been using for some time, and it works great. Unlike other posters here, I haven’t had issues with the scrollbar or mouse wheel (yet). I have CTRLEND programmed to go to the end of the DataGrid, and then it tracks the most-recently added items. I can scroll up through the DataGrid contents with the up key.
However, I have really weird behavior with the down key! If I start from the top of my DataGrid and hold the down key, it scrolls for a little bit and then eventually bounces back and forth between two adjacent rows. If I pgdn, it will scroll down more, then jump back to the topmost of the previous two rows that it would jump between, then scroll down to the point that I pgdn‘d to. If I page down some more, the down key will scroll to the end. If I go to the top of the DataGrid and start over, I get the exact same behavior, over and over again.
I’ve yet to find a post that addresses this, and I haven’t seen anything in the DataGrid documentation that helps.
It’s just a three-column DataGrid, where each column displays TextBlocks. Can anyone explain why just this one mode of scrolling is problematic? Here’s the XAML:
<DataGrid ItemsSource="{Binding MainLog}" AutoGenerateColumns="False"
Name="log_datagrid" SelectedCellsChanged="log_datagrid_SelectedCellsChanged"
KeyUp="datagrid_KeyUp" LoadingRow="log_datagrid_LoadingRow">
<DataGrid.Columns>
<!-- timestamp -->
<DataGridTemplateColumn Header="Timestamp">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Timestamp}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!-- level -->
<DataGridTemplateColumn Header="Level">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Level}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!-- error message -->
<DataGridTemplateColumn Header="Message">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Message}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
By the way, this behavior occurs even with all of my code-behind for the event handlers commented out.
Here is the definition of the struct that my MainLog collection contains:
public struct MainLogData
{
public string Timestamp { get; set; }
public string Level { get; set; }
public string Message { get; set; }
}
Ok… I reproduced the behavior with strings (simple list of strings bound to the data grid). The behavior started happening when I introduced duplicates strings in my list. It seems that the data grid gets confused between the “selected index” and the “selected value”.
The same kind of thing happens when I try to select a value (a string, in my test) that is present on another visible row: the selection gets screwed up: half of the time, the correct row is not selected.
Your problem is that you are using a “struct”. The simple solution to your problem is to make your struct a class:
Just changing the struct word to class should fix your problem.
You must understand that structs and classes are not the same, and structs determine their “equality” to another variable (with the same type) based on the values in them (2 variables of a specific structure type containing the same data will be considered equal). In the case of classes, unless specified otherwise, the equality is determined by its memory address; this ensures that by default no 2 instances of an object, even if they contain identical data, will not be considered equal because they do no reside at the same memory address (this behavior can be overwritten by overwriting “GetHashCode” and “Equals” methods in any class definition).
So in conclusion, the DataGrid has problems determining which item your are selecting (or moving too with your arrow key) because many objects in your list are considered “the same”, or “equal”. That is why it gets confused. Admittedly, I think this is a datagrid bug (or at least stranger behavior if it is by design), but changing your data type from a struct to a class should help you get back on track!
Cheers