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);
}
}
}
}
答案 0 :(得分:0)
我使用以下代码。
void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is DataGrid)
{
DataGrid grid = (sender as DataGrid);
if (grid.SelectedItem != null)
{
grid.Dispatcher.BeginInvoke(
(Action)(() =>
{
if (grid.SelectedItem != null)
{
grid.ScrollIntoView(grid.SelectedItem);
grid.UpdateLayout();
}
}));
}
}
}
它工作正常,但是最近我发现当我在我的datagrid中使用datagridcomboboxcolumn并且某些特定的窗口出现了您的问题时。
奇怪的是,在某些页面中被罚款,但在某些窗口中没有罚款
当datagridcomboboxcolumn具有itemsource并且正在滚动时,我发现是selectionchanged事件触发。
我不知道如何解决,所以我使用datagridtemplatecolumn并将combobox放在模板中
答案 1 :(得分:0)
在滚动/最大化窗口上触发事件...等等。这看起来像是datagrid错误。 根本原因:即使未触摸任何行,数据网格中一列或多列的内容也将触发触发selectionchanged事件。就我而言,这是由于Enum属性暴露给了datagrid。我必须将Enum属性更改为int属性,以避免选择更改甚至在滚动时触发。
人们在使用时报告了相同的行为: -列内的组合框 -列内的列表视图 -等等...
答案 2 :(得分:0)
我最近在带有ComboBoxColumn的DataGrid上遇到了相同的问题。通过检查OriginalSource
的{{1}}属性,我设法解决了这个问题。
当SelectionChanged事件由ComboBoxColumn引起时,OriginalSource属性是ComboBox控件。当SelectionChanged事件是由Datagrid引起的(例如,通过设置SelectedItem)时,OriginalSource是DataGrid本身。
这是对我有用的代码
SelectionChangedChangedEventArgs