Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

WPF - Window With TreeView - Slow Load With Virtualization

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
TheRealChrisHildebran
2933 Views, 5 Replies

WPF - Window With TreeView - Slow Load With Virtualization

TheRealChrisHildebran
Advocate
Advocate

A tool i'm building has a TreeView Control (Telerik RadTreeView) which will show all element instances in a Project/Active/Selection. The problem is that even with UI Virtualization the window load times are far too long. I'm not sure what to suspect now and am hoping one of the community has ran across this. 

 

Some examples of window load times below.

  • Project with around 150,000 model Element Instances it takes about 2 minutes to build.
  • Project with around 66,000 model Element Instances it takes about a minute to build
  • Project with less than 400 model Element Instances it takes about 5 seconds to build

 

Here is some additional pertinent information .

  1. I'm using WPF / XAML / MVVM / C# to build it.
  2. Ive timed the Filtered Element Collectors and found they are incredible fast and dont seem to be the issue.
  3. Ive submitted a support ticket to Telerik which only confirmed that the code should be working and does outside of Revit where I can create 180000 objects into 4 tiers in seconds.
  4. There are 4 tiers (See screenshot 1) of data arranged in the following manner
    • Tier 1: Category
      • Tier 2: Family Name
        • Tier 3: Type
          • Tier 4: Instance
  5. The TreeView is initially fully collapsed with only the first tier showing.
  6. Ive enabled UI Virtualization to show more as a user expands each node.
  7. Ive attached a zip file with the code in question

Screenshot #1

SS1.png

 

Screenshot #2

SS2.png

0 Likes

WPF - Window With TreeView - Slow Load With Virtualization

A tool i'm building has a TreeView Control (Telerik RadTreeView) which will show all element instances in a Project/Active/Selection. The problem is that even with UI Virtualization the window load times are far too long. I'm not sure what to suspect now and am hoping one of the community has ran across this. 

 

Some examples of window load times below.

  • Project with around 150,000 model Element Instances it takes about 2 minutes to build.
  • Project with around 66,000 model Element Instances it takes about a minute to build
  • Project with less than 400 model Element Instances it takes about 5 seconds to build

 

Here is some additional pertinent information .

  1. I'm using WPF / XAML / MVVM / C# to build it.
  2. Ive timed the Filtered Element Collectors and found they are incredible fast and dont seem to be the issue.
  3. Ive submitted a support ticket to Telerik which only confirmed that the code should be working and does outside of Revit where I can create 180000 objects into 4 tiers in seconds.
  4. There are 4 tiers (See screenshot 1) of data arranged in the following manner
    • Tier 1: Category
      • Tier 2: Family Name
        • Tier 3: Type
          • Tier 4: Instance
  5. The TreeView is initially fully collapsed with only the first tier showing.
  6. Ive enabled UI Virtualization to show more as a user expands each node.
  7. Ive attached a zip file with the code in question

Screenshot #1

SS1.png

 

Screenshot #2

SS2.png

5 REPLIES 5
Message 2 of 6

jeremytammik
Autodesk
Autodesk
Accepted solution

Dear Chris,

 

Thank you for your query.

 

I would suggest initially populating only the Tier 1, and then populating the other ones and their subnodes on demand when clicked by the user to open them.

 

If a specific node is never opened, there is no need to ever load its subnodes.

 

I am sure such techniques have already been implemented and published in the past.

 

In fact, I see a large number of solutions when searching the Internet for 'populate tree view on demand':

 

https://duckduckgo.com/?q=populate+tree+view+on+demand

 

I hope this helps.

 

Best regards,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Dear Chris,

 

Thank you for your query.

 

I would suggest initially populating only the Tier 1, and then populating the other ones and their subnodes on demand when clicked by the user to open them.

 

If a specific node is never opened, there is no need to ever load its subnodes.

 

I am sure such techniques have already been implemented and published in the past.

 

In fact, I see a large number of solutions when searching the Internet for 'populate tree view on demand':

 

https://duckduckgo.com/?q=populate+tree+view+on+demand

 

I hope this helps.

 

Best regards,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 6

TheRealChrisHildebran
Advocate
Advocate

Jeremy, thank you for your suggestions and for continuing to help me and the community!

 

Much has happened since last Wednesday and i can report back that i now have a virtualized TreeView which will quickly handles projects with 200,000+ model elements!

 

I will gladly share this solution with any needing it so if you're interested please contact me.

 

Initially, my inexperience drove me to go the "safe" route towards populating the TreeView but on thursday i deleted most of what id done and fully embraced MVVM and working with Objects, in an object, in an object, in an object! Was a mind melter for me but it really paid off!

 

The method below is truly the meat of the solution and along with the XAML in the previously attached ZIP file make it work. Way shorter and simpler than i thought it would be.

 

private static void InitializeDataSource()
		{
			Tier1CategoryNames = new ObservableCollection<Tier1Object>();
			Tier1Object tier1Object = null;
			Tier2Object tier2Object = null;
			Tier3Object tier3Object = null;
			Tier4Object tier4Object = null;

			foreach(var revitElementInstance in _revitElementInstances)
			{
				// ########## Tier 1 Start ##########
				var currentCategoryName = revitElementInstance.Category.Name;

				if(Tier1CategoryNames.Count == 0 || Tier1CategoryNames.All(tier1Object1 => tier1Object1.Tier1CategoryName != currentCategoryName))
				{
					Tier1CategoryNames.Add(tier1Object = new Tier1Object(currentCategoryName));
				}


				// ########## Tier 2 Start ##########
				var currentFamilyName = revitElementInstance.FamilyName;

				if(tier1Object.Tier2FamilyNames.Count == 0 || tier1Object.Tier2FamilyNames.All(tier2Object1 => tier2Object1.Tier2FamilyName != currentFamilyName))
				{
					tier1Object.Tier2FamilyNames.Add(tier2Object = new Tier2Object(currentFamilyName));
				}


				// ########## Tier 3 Start ##########
				var currentElementTypeName = revitElementInstance.ElementType.Name;

				if(tier2Object.Tier3ElementTypeNames.Count == 0 || tier2Object.Tier3ElementTypeNames.All(tier3Object1 => tier3Object1.Tier3ElementTypeName != currentElementTypeName))
				{
					tier2Object.Tier3ElementTypeNames.Add(tier3Object = new Tier3Object(currentElementTypeName));
				}


				// ########## Tier 4 Start ##########
				var currentElementInstanceName = revitElementInstance.ElementInstance.Name;

				tier3Object.Tier4ElementInstanceNames.Add(tier4Object = new Tier4Object(currentElementInstanceName));
			}
		}
0 Likes

Jeremy, thank you for your suggestions and for continuing to help me and the community!

 

Much has happened since last Wednesday and i can report back that i now have a virtualized TreeView which will quickly handles projects with 200,000+ model elements!

 

I will gladly share this solution with any needing it so if you're interested please contact me.

 

Initially, my inexperience drove me to go the "safe" route towards populating the TreeView but on thursday i deleted most of what id done and fully embraced MVVM and working with Objects, in an object, in an object, in an object! Was a mind melter for me but it really paid off!

 

The method below is truly the meat of the solution and along with the XAML in the previously attached ZIP file make it work. Way shorter and simpler than i thought it would be.

 

private static void InitializeDataSource()
		{
			Tier1CategoryNames = new ObservableCollection<Tier1Object>();
			Tier1Object tier1Object = null;
			Tier2Object tier2Object = null;
			Tier3Object tier3Object = null;
			Tier4Object tier4Object = null;

			foreach(var revitElementInstance in _revitElementInstances)
			{
				// ########## Tier 1 Start ##########
				var currentCategoryName = revitElementInstance.Category.Name;

				if(Tier1CategoryNames.Count == 0 || Tier1CategoryNames.All(tier1Object1 => tier1Object1.Tier1CategoryName != currentCategoryName))
				{
					Tier1CategoryNames.Add(tier1Object = new Tier1Object(currentCategoryName));
				}


				// ########## Tier 2 Start ##########
				var currentFamilyName = revitElementInstance.FamilyName;

				if(tier1Object.Tier2FamilyNames.Count == 0 || tier1Object.Tier2FamilyNames.All(tier2Object1 => tier2Object1.Tier2FamilyName != currentFamilyName))
				{
					tier1Object.Tier2FamilyNames.Add(tier2Object = new Tier2Object(currentFamilyName));
				}


				// ########## Tier 3 Start ##########
				var currentElementTypeName = revitElementInstance.ElementType.Name;

				if(tier2Object.Tier3ElementTypeNames.Count == 0 || tier2Object.Tier3ElementTypeNames.All(tier3Object1 => tier3Object1.Tier3ElementTypeName != currentElementTypeName))
				{
					tier2Object.Tier3ElementTypeNames.Add(tier3Object = new Tier3Object(currentElementTypeName));
				}


				// ########## Tier 4 Start ##########
				var currentElementInstanceName = revitElementInstance.ElementInstance.Name;

				tier3Object.Tier4ElementInstanceNames.Add(tier4Object = new Tier4Object(currentElementInstanceName));
			}
		}
Message 4 of 6

jeremytammik
Autodesk
Autodesk

Congratulations on the brilliant result!

 

Sometimes it helps tremendously to start over, build on your existing experience, throw out the baggage...

 

Thank you for sharing the solution.

  

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Congratulations on the brilliant result!

 

Sometimes it helps tremendously to start over, build on your existing experience, throw out the baggage...

 

Thank you for sharing the solution.

  

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 5 of 6

jeremytammik
Autodesk
Autodesk

Edited and shared for posterity by The Building Coder:

 

https://thebuildingcoder.typepad.com/blog/2019/03/forum-fran%C3%A7ais-and-treeview-performance.html

 

Thank you again!

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Edited and shared for posterity by The Building Coder:

 

https://thebuildingcoder.typepad.com/blog/2019/03/forum-fran%C3%A7ais-and-treeview-performance.html

 

Thank you again!

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 6 of 6

umesh.mhaskar
Contributor
Contributor

Thanks.!!  it will help

0 Likes

Thanks.!!  it will help

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report