DataGrid SelectionChanged event firing when scrolling

时间:2018-08-22 13:41:46

标签: wpf datagrid

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);
            }
        }
    }
}

3 个答案:

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