I am trying to implement a behavior to allow my DataGrid
to move to a newly added row at the bottom of the DataGrid
. I have buttons that add/remove items from the ItemsSource
and programatically set the SelectedCensusReportMapping
when adding a new row.
I found this solution (https://www.codeproject.com/Tips/125583/ScrollIntoView-for-a-DataGrid-when-using-MVVM) which does bring the newly added row into view within the DataGrid
. The issue I am having is that when I try to scroll the DataGrid
, the currently selected row always remains in view and I cannot scroll to other rows which would push the selected row off screen.
Here is the implementation of my DataGrid
:
<DataGrid Name="DataGrid_CensusReportMapping"
ItemsSource="{Binding Model.CensusReportMappings, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedCensusReportMapping, UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False">
<i:Interaction.Behaviors>
<h:ScrollIntoDataGridBehavior />
</i:Interaction.Behaviors>
</DataGrid>
If I step through the code via debug, I find that whenever the DataGrid
is scrolled, the behavior is firing. Why is the behavior firing simply by scrolling the DatGrid
. This happens anytime I scroll, regardless if by scrolling the selected item would remain on screen or get pushed off-screen.
Here is the behavior code:
public class ScrollIntoDataGridBehavior : Behavior<DataGrid>
{
/// <summary>
/// Override of OnAttached() method to add SelectionChanged event handler
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectionChanged += new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
}
/// <summary>
/// Override of OnDetaching() method to add SelectionChanged event handler
/// </summary>
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.SelectionChanged -=
new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
}
/// <summary>
/// When the selection is changed, re-focus on new selection using the ScrollIntoView method
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is DataGrid)
{
DataGrid grid = (sender as DataGrid);
if (grid.SelectedItem != null)
{
Action action = delegate()
{
grid.UpdateLayout();
if (grid.SelectedItem != null)
{
grid.ScrollIntoView(grid.SelectedItem, null);
}
};
grid.Dispatcher.BeginInvoke(action);
}
}
}
}