开发者

WPF: how to create complex user controls? (like GDI+)

开发者 https://www.devze.com 2023-01-31 18:03 出处:网络
For example, let\'s say I want to create something complex. like a zoommable/pannable graph. like google maps, or a stock market graph or something.

For example, let's say I want to create something complex. like a zoommable/pannable graph. like google maps, or a stock market graph or something.

XAML and that whole hierarchy doesn't really work. What I'm trying to do is kind of more like back in the day with GDI+/Winforms. Whe开发者_运维知识库re I could override paint i.e., "protected override void OnPaint(PaintEventArgs e)" and then I'd draw whatever the heck I wanted. Where I'd do double buffering. Like draw to a buffer and blip it to the screen.

But how do I go about this in WPF?


A fundamental difference between WPF and GDI/GDI+/WinForms is that WPF uses retained mode rendering (as opposed to the direct rendering of GDI). In a nutshell, this means that the system (actually, the hardware) is taking care of the double buffering for you. Instead of procedurally drawing to the screen / buffer, you rather declaratively provide a tree of vector objects and leave all the rendering to WPF.

The vector objects come in different levels of complexity / abstraction - the most low-level ones you might ever want to deal with are Visuals. The Shapes (Ellipse, Rectangle etc.) mentioned by David are already higher-level objects which can also handle user interaction like hit-testing etc.


You can use any of the WPF shapes, like Ellipse, Rectangle and then using the Canvas class you can move them:

var rect = new Rectangle();
//...set width, height...
Canvas.SetTop(rect, 10);
Canvas.SetLeft(rect, 15);

This should get you started. Keep in mind that zooming, stretching content, traslating and rotations can all be achieved using math functions, but don't panic! WPF's got some cut things about it too:

var rotateTransform1 = new RotateTransform(45);
rect.RenderTransform = rotateTransform1;


If you really, really want it, you can derive your control from UIElement or FrameworkElement and override OnRender where you will get a DrawingContext object which provides methods for drawing shapes, text, images.

But if you want to work in the WPF's philosophy and spirit, probably 99% of the times you don't need to override OnRender. WPF offers a lot (and I really mean A LOT) of ways to develop new controls by styling, templating and if these two don't do the job, then subclassing the appropriate control in the WPF's controls hierarchy.

As gstercken very good pointed before, WPF is not WinForms, you must think in WPF in order to do a good work.

0

精彩评论

暂无评论...
验证码 换一张
取 消