Animation Inside Advertiser (OnRender Call)

I use Adorner in .NET 3.5, and I can draw by overriding OnRender, but I need the ability to redraw the advertiser to change its appearance.

Essentially, I'm looking for a way to clear the drawing context and call OnRender again. What is the best way to do this, or is there a better approach?

public class MyAdorner : Adorner { private Brush brush = Brushes.Red; public DragArrowAdorner(UIElement adornedElement) : base(adornedElement) {} public void RedrawWithBrush(Brush newBrush) { brush = newBrush; // redraw..? } protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) { // some drawing code... drawingContext.DrawRectangle( brush, null, new Rect(AdornedElement.DesiredSize)); } } 
+6
c # wpf adorner
source share
2 answers

The answer to your question is to use InvalidateVisual to call OnRender to call again

However, I would suggest instead of doing my own drawing on OnRender myself, to use the standard style and templating visual tree to create the actual visual adorner. It also means that you can run standard XAML animations inside it using a storyboard.

If you want to go with this approach, in your adorner class you need:

  • in the constructor, either call base.AddVisualChild() , or create your own collection of visual images with the visual effects that you want to show in adorner
  • Override ArrangeOverride(Size size) to position children correctly
  • override VisualChildrenCount to return the number of children in the adorner visual tree;
  • override GetCisualChild(int index) to return a specific child.

You can see the ResizeAdorner MSDN sample for more information.

+10
source share

It is very important to understand that WPF is not like Windows.Forms. OnRender() should really be called AccumulateDrawingObjects() , because that's what it does. WPF accumulates a bunch of drawing objects that it saves in order to be able to draw the user interface when necessary. The magic of effectively updating the user interface is that you can really change the objects in this visual tree after OnRender() .

For example, you can create a DrawingGroup and put it in a DrawingContext during OnRender . Then at any time when you want to change the visual, you can DrawingGroup.Open() , put new drawing commands in it, and WPF will effectively DrawingGroup.Open() this part of the user interface.

It looks like this:

 DrawingGroup backingStore = new DrawingGroup(); protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); Render(); // put content into our backingStore drawingContext.DrawDrawing(backingStore); } // I can call this anytime, and it'll update my visual drawing // without ever triggering layout or OnRender() private void Render() { var drawingContext = backingStore.Open(); Render(drawingContext); drawingContext.Close(); } 
+1
source share

All Articles