Example T1118340
Visible to All Users

WPF Tree List - Load Nodes Asynchronously Without Locking the Application's UI

This example creates the asynchronous child nodes selector and fetches child nodes in a background thread. During the fetch operation, parent nodes display a loading indicator and the TreeListView remains responsive to user actions.

TreeListView_Async_Loading

Files to Review

Documentation

More Examples

Example Code

AsyncChildNodesSelector/MainWindow.xaml
XAML
<Window 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:AsyncChildNodesSelector" xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" x:Class="AsyncChildNodesSelector.MainWindow" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.DataContext> <local:ViewModel/> </Window.DataContext> <Window.Resources> <local:CustomChildrenSelector x:Key="childrenSelector"/> </Window.Resources> <Grid> <dxg:TreeListControl ItemsSource="{Binding DataItems}" AutoGenerateColumns="AddNew" EnableSmartColumnsGeneration="True"> <dxg:TreeListControl.View> <dxg:TreeListView TreeDerivationMode="ChildNodesSelector" ChildNodesSelector="{StaticResource childrenSelector}"/> </dxg:TreeListControl.View> </dxg:TreeListControl> </Grid> </Window>
AsyncChildNodesSelector/AsyncChildNodesSelector.cs(vb)
C#
using DevExpress.Xpf.Grid; using System; using System.Collections; using System.Threading; using System.Threading.Tasks; namespace AsyncChildNodesSelector { public class CustomChildrenSelector : IAsyncChildNodesSelector { public Task<bool> HasChildNode(object item, CancellationToken token) { return Task.Run(async () => { for (int i = 0; i < 10; i++) { token.ThrowIfCancellationRequested(); await Task.Delay(25); } return !(item is StageTask); }); } public IEnumerable SelectChildren(object item) { throw new NotImplementedException(); } public Task<IEnumerable> SelectChildrenAsync(object item, CancellationToken token) { return Task.Run(async () => { for (int i = 0; i < 10; i++) { token.ThrowIfCancellationRequested(); await Task.Delay(100); } return SelectChildNodes(item); }); } public IEnumerable SelectChildNodes(object item) { if (item is ProjectStage) return (item as ProjectStage).Tasks; else if (item is ProjectObject) return (item as ProjectObject).Stages; return null; } } }
AsyncChildNodesSelector/ViewModel.cs(vb)
C#
using DevExpress.Mvvm; using System; using System.Collections.ObjectModel; namespace AsyncChildNodesSelector { public class ViewModel : ViewModelBase { public ObservableCollection<ProjectObject> DataItems { get; set; } public ViewModel() { DataItems = InitData(); } private ObservableCollection<ProjectObject> InitData() { ObservableCollection<ProjectObject> projects = new ObservableCollection<ProjectObject>(); ProjectObject betaronProject = new ProjectObject() { Name = "Project: Betaron", Stages = new ObservableCollection<ProjectStage>() }; ProjectObject stantoneProject = new ProjectObject() { Name = "Project: Stanton", Stages = new ObservableCollection<ProjectStage>() }; InitBetaronProjectData(betaronProject); InitStantoneProjectData(stantoneProject); projects.Add(betaronProject); projects.Add(stantoneProject); return projects; } void InitBetaronProjectData(ProjectObject betaronProject) { betaronProject.Executor = "Mcfadyen Ball"; ProjectStage stage21 = new ProjectStage() { Name = "Information Gathering", Executor = "Kaiden Savastano", Tasks = new ObservableCollection<StageTask>() }; stage21.Tasks.Add(new StageTask() { Name = "Market research", Executor = "Carmine Then", StartDate = new DateTime(2011, 10, 1), EndDate = new DateTime(2011, 10, 5), State = "Completed" }); stage21.Tasks.Add(new StageTask() { Name = "Making specification", Executor = "Seto Kober", StartDate = new DateTime(2011, 10, 5), EndDate = new DateTime(2011, 10, 10), State = "In progress" }); ProjectStage stage22 = new ProjectStage() { Name = "Planning", Executor = "Manley Difrancesco", Tasks = new ObservableCollection<StageTask>() }; stage22.Tasks.Add(new StageTask() { Name = "Documentation", Executor = "Martez Gollin", StartDate = new DateTime(2011, 10, 15), EndDate = new DateTime(2011, 10, 16), State = "Not started" }); ProjectStage stage23 = new ProjectStage() { Name = "Design", Executor = "Clint Mary", Tasks = new ObservableCollection<StageTask>() }; stage23.Tasks.Add(new StageTask() { Name = "Design of a web pages", Executor = "Gasper Hartsell", StartDate = new DateTime(2011, 10, 13), EndDate = new DateTime(2011, 10, 14), State = "Not started" }); stage23.Tasks.Add(new StageTask() { Name = "Pages layout", Executor = "Shirish Huminski", StartDate = new DateTime(2011, 10, 13), EndDate = new DateTime(2011, 10, 14), State = "Not started" }); ProjectStage stage24 = new ProjectStage() { Name = "Development", Executor = "Edwin Thone", Tasks = new ObservableCollection<StageTask>() }; stage24.Tasks.Add(new StageTask() { Name = "Design", Executor = "Zarko Knill", StartDate = new DateTime(2011, 10, 27), EndDate = new DateTime(2011, 10, 28), State = "Not started" }); stage24.Tasks.Add(new StageTask() { Name = "Coding", Executor = "Harley Kirckof", StartDate = new DateTime(2011, 10, 29), EndDate = new DateTime(2011, 10, 30), State = "Not started" }); ProjectStage stage25 = new ProjectStage() { Name = "Testing and Delivery", Executor = "Boucher Hislop", Tasks = new ObservableCollection<StageTask>() }; stage25.Tasks.Add(new StageTask() { Name = "Testing", Executor = "Sarah Ragas", StartDate = new DateTime(2011, 10, 13), EndDate = new DateTime(2011, 10, 14), State = "Not started" }); stage25.Tasks.Add(new StageTask() { Name = "Content", Executor = "Rashid Terinoni", StartDate = new DateTime(2011, 10, 13), EndDate = new DateTime(2011, 10, 14), State = "Not started" }); betaronProject.Stages.Add(stage21); betaronProject.Stages.Add(stage22); betaronProject.Stages.Add(stage23); betaronProject.Stages.Add(stage24); betaronProject.Stages.Add(stage25); } void InitStantoneProjectData(ProjectObject stantoneProject) { stantoneProject.Executor = "Ruben Ackerman"; ProjectStage stage11 = new ProjectStage() { Name = "Information Gathering", Executor = "Huyen Trinklein", Tasks = new ObservableCollection<StageTask>() }; stage11.Tasks.Add(new StageTask() { Name = "Market research", Executor = "Tanner Crittendon", StartDate = new DateTime(2011, 10, 1), EndDate = new DateTime(2011, 10, 5), State = "Completed" }); stage11.Tasks.Add(new StageTask() { Name = "Making specification", Executor = "Carmine Then", StartDate = new DateTime(2011, 10, 5), EndDate = new DateTime(2011, 10, 10), State = "Completed" }); ProjectStage stage12 = new ProjectStage() { Name = "Planning", Executor = "Alfredo Sookoo", Tasks = new ObservableCollection<StageTask>() }; stage12.Tasks.Add(new StageTask() { Name = "Documentation", Executor = "Gorf Wobbe", StartDate = new DateTime(2011, 10, 13), EndDate = new DateTime(2011, 10, 14), State = "Completed" }); ProjectStage stage13 = new ProjectStage() { Name = "Design", Executor = "Saphire Plump", Tasks = new ObservableCollection<StageTask>() }; stage13.Tasks.Add(new StageTask() { Name = "Design of a web pages", Executor = "Dominic Minden", StartDate = new DateTime(2011, 10, 13), EndDate = new DateTime(2011, 10, 14), State = "In progress" }); stage13.Tasks.Add(new StageTask() { Name = "Pages layout", Executor = "Pinkerton Trezise", StartDate = new DateTime(2011, 10, 13), EndDate = new DateTime(2011, 10, 14), State = "In progress" }); ProjectStage stage14 = new ProjectStage() { Name = "Development", Executor = "Lauren Partain", Tasks = new ObservableCollection<StageTask>() }; stage14.Tasks.Add(new StageTask() { Name = "Design", Executor = "Delilah Beamer", StartDate = new DateTime(2011, 10, 23), EndDate = new DateTime(2011, 10, 24), State = "In progress" }); stage14.Tasks.Add(new StageTask() { Name = "Coding", Executor = "Dunaway Dupriest", StartDate = new DateTime(2011, 10, 25), EndDate = new DateTime(2011, 10, 26), State = "Not started" }); ProjectStage stage15 = new ProjectStage() { Name = "Testing and Delivery", Executor = "Christos Arrant", Tasks = new ObservableCollection<StageTask>() }; stage15.Tasks.Add(new StageTask() { Name = "Testing", Executor = "Grice Ohora", StartDate = new DateTime(2011, 10, 13), EndDate = new DateTime(2011, 10, 14), State = "Not started" }); stage15.Tasks.Add(new StageTask() { Name = "Content", Executor = "Christos Arrant", StartDate = new DateTime(2011, 10, 13), EndDate = new DateTime(2011, 10, 14), State = "Not started" }); stantoneProject.Stages.Add(stage11); stantoneProject.Stages.Add(stage12); stantoneProject.Stages.Add(stage13); stantoneProject.Stages.Add(stage14); stantoneProject.Stages.Add(stage15); } } }

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.