locked
Calling DataGrid ScrollToView with the CollectionViewSource current item from XAML instead of code behind? RRS feed

  • Question

  • In my XAMl I define my DataGrid like this:

    <DataGrid x:Name="gridStudents" ItemsSource="{Binding Source={StaticResource cvsStudentList}}"
    		Margin="2"
    		Height="250"
    		SelectedItem="{Binding SelectedStudentItem, UpdateSourceTrigger=PropertyChanged}"
    		AutoGenerateColumns="False" IsReadOnly="True" IsSynchronizedWithCurrentItem="True" SelectionChanged="gridStudents_SelectionChanged">
    


    As you see, I added a SelectionChanged event handler:

            private void gridStudents_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (gridStudents.SelectedItem != null)
                    gridStudents.ScrollIntoView(gridStudents.SelectedItem);
            }

    Since it is the CollectionViewSource that is my go-between, I have to keep the grid up to date and ensure the item that the CVS selected is now visible to the user.

    All works fine. But can this activity be done in the XAML rather than code behind?

    Sunday, June 26, 2016 6:52 PM

Answers

  • You can't do that in xaml code but, if you are using mvvm pattern then Bhaviors  will help you.

    I am using Expression blend interactivity dll, that can be downloaded from nuget package manager "Install-Package Blend.Interctivity.WPF.v4.0"

     public class DataGridBehavior  : Behavior<DataGrid>  {
            protected override void OnAttached()
            {
                base.OnAttached();
                this.AssociatedObject.SelectionChanged += new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
            }
            void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (sender is DataGrid)
                {
                    DataGrid grid = (sender as DataGrid);
                    if (grid.SelectedItem != null)
                    {
                        grid.Dispatcher.BeginInvoke((Action)( () =>
                        {
                            grid.UpdateLayout();
                            grid.ScrollIntoView(grid.SelectedItem, null);
                        }));
                    }
                }
            }
            protected override void OnDetaching()
            {
                base.OnDetaching();
                this.AssociatedObject.SelectionChanged -=
                    new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
            }
        }
    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication1"
            mc:Ignorable="d"
           xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
            Title="MainWindow" Height="350" Width="525">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="100"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <DataGrid AutoGenerateColumns="True" SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                      ItemsSource="{Binding Path=Employees, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="gt" Grid.Row="0">
                <i:Interaction.Behaviors>
                    <local:DataGridBehavior></local:DataGridBehavior>
                </i:Interaction.Behaviors>
            </DataGrid>
            <Button Content="Add" Click="Button_Click" Grid.Row="1"></Button>
        </Grid>
    </Window>
    



    Thanks & Regards
    Syed Amjad Sr. Silverlight/WPF Developer,
    yahoo : syedamjad6736@yahoo.com, skype : syedamjad.0786.
    Please use Marked as Answer if my post solved your problem and use Vote As Helpful if a post was useful.

    • Marked as answer by DotNet Wang Sunday, July 10, 2016 8:45 AM
    Monday, June 27, 2016 11:26 AM

All replies

  • Hi chuckie,

    You can select an row from the grid only when it is in view area, when the row is already view-able, then why to scroll till the item. Are you trying to display the selected item as top row in the grid or what?

    Let me know your exact issue.



    Thanks & Regards
    Syed Amjad Sr. Silverlight/WPF Developer,
    yahoo : syedamjad6736@yahoo.com, skype : syedamjad.0786.
    Please use Marked as Answer if my post solved your problem and use Vote As Helpful if a post was useful.

    Monday, June 27, 2016 4:31 AM
  • Hi

    I have a button to add / edit an entry. This displays a popup window to fill with data (I don't want to use an editable grid).

    User makes changes and clicks OK. If it is a new entry, then it might not be visible, eg: their name is lower in the sorted list. Thus I have to ensure it is now visible and not just selected.

    Thanks.

    Monday, June 27, 2016 5:01 AM
  • You can't do that in xaml code but, if you are using mvvm pattern then Bhaviors  will help you.

    I am using Expression blend interactivity dll, that can be downloaded from nuget package manager "Install-Package Blend.Interctivity.WPF.v4.0"

     public class DataGridBehavior  : Behavior<DataGrid>  {
            protected override void OnAttached()
            {
                base.OnAttached();
                this.AssociatedObject.SelectionChanged += new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
            }
            void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (sender is DataGrid)
                {
                    DataGrid grid = (sender as DataGrid);
                    if (grid.SelectedItem != null)
                    {
                        grid.Dispatcher.BeginInvoke((Action)( () =>
                        {
                            grid.UpdateLayout();
                            grid.ScrollIntoView(grid.SelectedItem, null);
                        }));
                    }
                }
            }
            protected override void OnDetaching()
            {
                base.OnDetaching();
                this.AssociatedObject.SelectionChanged -=
                    new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
            }
        }
    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication1"
            mc:Ignorable="d"
           xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
            Title="MainWindow" Height="350" Width="525">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="100"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <DataGrid AutoGenerateColumns="True" SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                      ItemsSource="{Binding Path=Employees, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="gt" Grid.Row="0">
                <i:Interaction.Behaviors>
                    <local:DataGridBehavior></local:DataGridBehavior>
                </i:Interaction.Behaviors>
            </DataGrid>
            <Button Content="Add" Click="Button_Click" Grid.Row="1"></Button>
        </Grid>
    </Window>
    



    Thanks & Regards
    Syed Amjad Sr. Silverlight/WPF Developer,
    yahoo : syedamjad6736@yahoo.com, skype : syedamjad.0786.
    Please use Marked as Answer if my post solved your problem and use Vote As Helpful if a post was useful.

    • Marked as answer by DotNet Wang Sunday, July 10, 2016 8:45 AM
    Monday, June 27, 2016 11:26 AM