I’m working on a org chart project(SL 3) and I’m seeing the UI thread hang when the chart is building around 2,000 nodes and when it renders it takes about a min and then FPS drop to a crawl.
Here is the code flow. Page.xaml.cs calls a wcf service that returns a list of AD users. Then we use Linq to build a collection of nodes to bind to the Orgchart.cs
OrgChart.cs is a canvas and displays a collection of nodes and connecting lines.
Node.cs is a canvas and has user data can contain children nodes.
NodeContent.xaml is a user control that has borders so I can set the background, textblocks to display user's data, Events that handle the selected and expaned nodes, and storyboards that resize the nodes when they are selected or expanded.I noticed during hours of debugging , here in the InitializeComponent(); section where it loads the xaml it seems to be where the preformance hit is happening.
System.Windows.Application.LoadComponent(this, new System.Uri("/Silverlight.Custom;component/NodeContent.xaml", System.UriKind.Relative));
So I guess I have two questions.
- Can threading help in any way with the UI thread hanging while drawing the nodes?
- How can I avoid the hit when calling this user control?
Any advi开发者_StackOverflow中文版ce or direction anyone can lend would be greatly appreciated.
Thanks, KC
Sounds to me like your UI has a natural point for comparmentalising the load by loading UI for nodes on-demand.
You have nodes that can be expanded and collapsed. Only load the UI for the nodes currently expanded. As the user expands a node then load the UI for its child nodes at that point.
As far as doing anything with the UI threading is going to get you nowhere. You might be able to do some data massaging on background threads, but if you mess with any objects that are databound to UI on a background thread you are looking for trouble. You will really need to split out this work from the UI, and then invoke it back over.
My guess is that Siverlight is simply taking a while to draw all of the nodes. We have an application which draws around 100 fairly rich widgets. Only about 20 or 30 widgets are visible in an ItemsControl host a wrap panel. We ended up getting better performance by using a virtualizing wrap panel, which doesn't actually instantiate the hidden UI elements until they are needed. There are some trade-offs here, and we are still working the problem, but the page loads much faster this way. You might take a similar strategy drawing your nodes, only loading the nodes that need to be visible. Also, you could load portions of the tree onto the drawing surface in lumps. Perhaps take the first 100 records and draw those, then draw the next 100, etc.
精彩评论