I have a complex WPF control that draws a lot of primitives in its OnRender (it's sort of like a map). When a small portion of it changes, I'd only like to re-issue render commands for the affected elements, instead of running the entire OnRender over. While I'm fine with my OnRender function's performance on a resize or whatever, it's not fast enough for mouse hover-based highlighting of primitives.
Currently the only way I know how to force a screen update is to call InvalidateVisual(). No way to send in a dirty rect region to invalidate.
Is the lowest granularity of WPF screen composition the UI element? Will I need to do my renders of primitives into an intermediate target and then have that use InvalidateVisual() to update to the screen?
When you want to write WPF custom/composite controls, you should try to avoid overriding OnRender as possible especially if you plan to invalidate portions of it. It's much easier to use AddVisualChild + override VisualChildrenCount + override GetVisualChild + override Measure & Arrange like this (pseudo code with 2 children):
private void BuildMyControls()
{
AddVisualChild(subControl1);
AddVisualChild(subControl2);
}
protected override int VisualChildrenCount
{
get
{
return 2;
}
}
protected override Visual GetVisualChild(int index)
{
if (index == 0) return subControl1;
if (index == 1) return subControl2;
return null; // should never be called in fact...
}
protected override Size MeasureCore(Size availableSize)
{
base.Measure...
BuildMyControls();
.. measure them, probably call subControlX.Measure(...);
}
protected override void ArrangeCore(Rect finalRect)
{
base.ArrangeCore(finalRect);
... arrange them, probably call subControlX.Arrange
}
With this kind of code, you can invalidate just one portion, with something like subControlX.InvalidateXXX();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With