I want to draw something dynamically. Following code shows my OnRender. I'm setting DrawItem somewhere in my program where I need it. But when I'm calling DrawItem =5;
what do I have to call, so that OnRender gets called?
protected override void OnRender(DrawingContext drawingContext)
{
switch (DrawItem)
{
case 1:
//Draw Item
break;
case 2:
//Draw Item
break;
case 3:
//Draw Item
break;
case 4:
//Draw Item
break;
case 5:
//Draw Item
break;
}
base.OnRender(drawingContext)
}
public int DrawItem { get; set; }
Your question is not clear but from what I can understand you seem to be asking for a method to refresh the visuals after updating your drawing variables. You could use the following after updating your drawing variables:
this.InvalidateVisual();
and with the property:
private int drawItem;
pulic int DrawItem
{
get {return drawItem;}
set
{
drawItem=value;
this.InvalidateVisual();
}
}
If the size of your control changes, you can use InvalidateVisual()
, however keep in mind this causes a fairly expensive re-layout of your UI. If the size of your control is staying the same, you shouldn't call InvalidateVisual()
.
A more efficient way to update your UI is to create a DrawingGroup
"backing store" and add it to the DrawingContext
during OnRender()
. You can then update it whenever you like, using DrawingGroup.Open()
, and WPF will update your UI.
If this sounds confusing, remember that WPF is a retained drawing system. That means OnRender()
might better be called AccumulateDrawingObjects()
. It's actually accumulating a tree of live drawing objects, some of which (like DrawingGroup, RenderTargetBitmap, and WriteableBitmap) can be updated later.
This is what it looks like:
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();
}
I ran into similar issue and found an even more elegant solution. Define a DependencyProperty like so:
public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register("PropertyName", typeof(PropertyType), typeof(PropertyElementType), new FrameworkPropertyMetadata(DefaultPropertyValue, FrameworkPropertyMetadataOptions.AffectsRender));
The key here is this:
FrameworkPropertyMetadataOptions.AffectsRender
So now the property can be set in XAML and updates visual automatically on changing.
http://msdn.microsoft.com/de-de/library/ms598919(v=vs.100).aspx
You have to call InvalidateVisual for the Control that shall be updated. But as you can read, a call to InvalidateVisual causes a complete layout cycle, so be sure for performance reasons that your canvas or whatever you want to draw on contains no or only a few child elements.