How can I suspend and resume layout in WPF?
How can I suspend and resume layout in WPF? I hear开发者_JAVA百科d that this is not necessary. But this is extremely necessary!
I process a lot of change positions, and if they are rendered one by one, it creates a delay effect.
Here are some code:
CompositionTarget.Rendering += new EventHandler(Draw);
void Draw(object sender, EventArgs e)
{
//Clean screen
for (int i = mainCanvas.Children.Count - 1; i > -1; i--)
{
if (mainCanvas.Children[i] is PlayerUserControl || mainCanvas.Children[i] is Image)
{
mainCanvas.Children.Remove(mainCanvas.Children[i]);
}
}
//DRAW FLOOR AROUND
FloorService.FloorEntity[] floorsAround = floorService.selectFloorsAround(Player.id);
for...
{
Image image = new Image();
image.Source = new BitmapImage(new Uri("/" + floorsAround[i].ImageSource, UriKind.Relative));
mainCanvas.Children.Add(image);
}
//DRAW PLAYERS AROUND
//Its similar as draw floors around.
...
}
WPF is a retained composition engine. What it means is you don't have to do the rendering yourself hooking the Rendering
event, but rather compose an image using nodes that you will put in a tree. See here for details on WPF architecture: WPF Architecture. I can assure you if you understand perfectly this document as well as the Layout System link Rick Sladkey sent, you should also understand why you should change your code if you want to continue with WPF.
If you play it right with WPF (ie: use dependency properties, override Measure & Arrange methods for example), you will see it's a very powerful engine capable of displaying thousands of nodes in the graphical tree. I suggest another useful reading: ZoomableApplication2: A Million Items
You haven't given enough information except to say that your "process a lot of changes". But if you make all those changes:
- sequentially
- from the UI thread
- without calling
UpdateLayout
, and - without returning
then no layout occurs in-bewteen those changes. Therefore there is nothing to suspend or resume because layout is always deferred until after you return from making these kinds of changes.
So, if you are experiencing delays, then is is not because your are not batching your layout changes ala WinForms. As a result, the only way to reduce the delay, if it is indeed due to layout, is to avoid unnecessary layout recalculations. Again, without knowing what you are doing, it is impossible to suggest anything concrete. But there are many properties you can avoid to might trigger a recursive layout pass. See Layout Performance Considerations in this article:
- Layout System
Have you considered removing the canvas from the window first which would hide it, then clear and re-add all your items to the canvas, then re add the canvas back to the window?
He clearly posted enough info that even I with limited wpf experience knew exactly what he was talking about.
So in short, he has a process whereby elements are being added / or manipulated (I assume in loop) and he wishes to freeze the rendering process whilst in the loop as that is being performed because I assume 1. You can see the rendering taking place and 2. It’s slow
There was a post above that mentioned removing the canvas first... well that’s almost it. Just set the visibility of the main parent to collapsed, perform the element add/manipulation, then make the parent visible
精彩评论