Как использовать WPF TreeView HierarchicalDataTemplate с LINQ to Entities?

У меня есть класс Page в моем файле модели данных Entity Data .edmx ADO.NET со свойствами Parent и Children. Это для иерархии страниц.

удалена неработающая ссылка ImageShack - класс иерархической страницы ADO.NET Entity Framework

Это обрабатывается в моей базе данных SQL с помощью внешнего ключа ParentId в таблице страниц, привязанного к первичному ключу Id той же таблицы страниц.

Как мне отобразить эту иерархию в WPF TreeView?


person Community    schedule 06.11.2008    source источник
comment
Ссылка на ваше изображение не работает. Если у вас все еще есть исходное изображение, повторно загрузите его в stack.imgur или просто отредактируйте свой вопрос, чтобы он работал без изображения. Спасибо.   -  person Ilmari Karonen    schedule 27.07.2015


Ответы (3)


Я получил это с помощью Эйба Хайдебрехта. Большое ему спасибо.

Вот мой XAML ...

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:PageManager"
    Title="Window1" Height="300" Width="300" Name="Window1">
    <Grid>
        <TreeView Margin="12" Name="TreeViewPages" ItemsSource="{Binding}" TreeViewItem.Expanded="TreeViewPages_Expanded">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type local:Page}" ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Path=ShortTitle}" />
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</Window>

Вот мой код Visual Basic ...

Class Window1

    Private Sub Window1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        Dim db As New PageEntities
        Dim RootPage = From p In db.Page.Include("Children") _
                       Where (p.Parent Is Nothing) _
                       Select p
        TreeViewPages.ItemsSource = RootPage
    End Sub

    Private Sub TreeViewPages_Expanded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        Dim ExpandedTreeViewItem As TreeViewItem = DirectCast(e.OriginalSource, TreeViewItem)
        Dim PageId As Guid = DirectCast(ExpandedTreeViewItem.DataContext, Page).Id
        Dim db As New PageEntities
        Dim ChildPages = From p In db.Page.Include("Children") _
                         Where p.Parent.Id = PageId _
                         Select p
        ExpandedTreeViewItem.ItemsSource = ChildPages
    End Sub
End Class

Когда окно загружается, корневой узел и его дочерние элементы запрашиваются из базы данных и вставляются в дерево.

Каждый раз, когда узел раскрывается, его дочерние элементы и внуки запрашиваются из базы данных и вставляются в дерево.

person Community    schedule 07.11.2008
comment
С таким выделенным кодом вы можете использовать DataTemplate вместо <HierarchicalDataTemplate DataType="{x:Type local:Page}" ItemsSource="{Binding Children}"> - person 0x49D1; 16.05.2011

Другой способ: (ну очень похоже, но немного по-другому)

В вашей функции оконной загрузки:

PageEntities db = new PageEntities();
TreeViewPages.ItemsSource = db.Page.Where(u=>u.Parent==null);

Создайте новый файл Page.cs

public partial class Page {
    public ObjectQuery<Page> LoadedChildren {
        get {
            var ret = Children;
            if(ret.IsLoaded==false) ret.Load();
            return ret;
        }
    }
}

В вашем XAML:

<TreeView Name="TreeViewPages">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemSource="{Binding LoadedChildren}">
            <TextBlock Text="{Binding ShortTitle}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

Это не тестировалось, но вы должны получить общее представление.

person Community    schedule 17.03.2009
comment
Этот метод загружает сразу всю иерархию. Ранее принятый ответ - загрузка дочерних узлов по запросу. - person Mike Christiansen; 17.03.2009

Второе решение сработало для меня лучше всего. У меня есть список рекурсивных объектов, так что это XAML, который я использовал:

<TreeView Height="Auto" HorizontalAlignment="Stretch" Name="trvVaults" VerticalAlignment="Stretch" Width="Auto" Grid.Column="0" Margin="5">
    <!--  Treeview ItemsSource is loaded programmatically  -->
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Vaults}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

Каждый объект «Хранилище» имеет несколько свойств (имя, местоположение и т. Д.) И общий список «Хранилищ».

person Community    schedule 29.01.2011