0

I would like to set up a datagrid so that whenever an item is added to its itemssource the datagrid scrolls down to show the last item.

The datagrid is inside a datatemplate, so i cannot set the X:name property and access it directly from the codebehind.

What I have in mind is to use a datagrid event that fires when a row is added and has the grid scroll itself.

Here's some psuedo code that outlines how I have things set up:


UI.XAML exerpt

<TabControl ItemsSource="{Binding Parents}" x:Name="ProductsTab">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Key}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <DataGrid Margin="5" ItemsSource="{Binding Value.Children}">
                <DataGrid.Columns>
                    <Column Column definitions removed for your sanity/>
                </DataGrid.Columns>
            </DataGrid>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

UI.XAML.CS exerpt

public class UI
{
    //Thanks to Dr. WPF for the ObservableDictionary class
    public ObservableDictionary<string, Parent> Parents {get; set;}
}

Parent.CS

public class parent
{
    public ObservableCollection<Child> Children {get; set;}
}

The datagrids are not editable.

In case you're wondering, I have read the post "How to autoscroll on WPF datagrid" the code in that post would work for me if I could find an event that fires whenever an item is added to the datagrid itemssource.

Any Ideas?

Eric
  • 1,392
  • 17
  • 37

2 Answers2

0

Combine the autoscrolling idea with the idea from this question or this MSDN thread: instead of listening to your grid's event to detect row additions, listen to the events from the ItemsSource.

Edit: Since you don't like that suggestion, you could try hooking LoadingRow, but I strongly suspect this will require EnableRowVirtualization = false in order to work (I haven't tried it). If your collection gets large, turning off row virutalization opens up the possibility of a serious performance hit.

Community
  • 1
  • 1
Esoteric Screen Name
  • 6,082
  • 4
  • 29
  • 38
  • quoting the question: "This keeps your business logic with your business objects." The opposite is true in my case, that would mix my business logic with my view logic. I'll add some sample code to the original question. – Eric Dec 02 '11 at 18:25
  • I disagree that listening to `ObservableDictionary` events in this fashion is "business logic". You aren't doing anything with/to your business objects like the asker of the linked question. You're having your UI layer listen to what your business layer is already doing, and you're implementing it (or ought to be) in your code behind. It's presentation logic performed in the presentation layer. Regardless, I've added another suggestion to my answer, but it's not as good of an idea. – Esoteric Screen Name Dec 02 '11 at 19:44
  • The LoadingRow event works, and you can leave EnableRowVirtualization set to true. I could swear I already tried that event! – Eric Dec 03 '11 at 00:04
0

you can access the DataGrid, even if it is in a DataTemplate, by doing a 'search' in the visual tree : VisualTreeHelper.GetChildCount // VisualTreeHelper.GetChild , then test again the type until you find your grid. And you might seek with same kind of methods the ScrollBar, and then you can hook an event handler and use a code-behind logic.

GameAlchemist
  • 18,995
  • 7
  • 36
  • 59
  • I still need an event that tells me if an item has been added to the datagrid's collection. – Eric Dec 02 '11 at 18:28
  • mmm well so the question is : which event to hook. Since DataGrid is a Framework element, you might use the SourceUpdated event. Check inside that handler that this is the right binding that you're listening to otherwise it might lead to strange behaviours later on :-) – GameAlchemist Dec 02 '11 at 19:31
  • I like the looks of that binding expression, let me check it out. – Eric Dec 02 '11 at 23:50