如何在WPF中绘制窗口(最佳实践)?
我正在尝试编写一个类似于交互式游戏的小应用程序,我需要有一个Draw
方法,它将在屏幕上绘制,但无法弄清楚如何构建WPF方法。
如果这是Winforms
,我可以使用:
public void Draw (Graphics g) { }
但是对于WPF Window
,我应该在xaml中拥有什么(目前只有一个Grid
),这个Draw
方法应该作为参数接收什么?
首先,我想这样做才能让它工作,然后我可以考虑如何使它更多WPF
等。但现在我更感兴趣的是让它工作。
通常,您以完全不同的方式在WPF中“绘制”。
在Windows Forms / GDI中,图形API是立即模式图形API。 每次刷新/无效窗口时,都使用Graphics显式绘制内容。
然而,在WPF中,事情的工作方式不同。 你很少直接画 – 相反,它是一个保留模式图形API。 你告诉WPF你想要对象的位置,它会为你处理绘图。
想到它的最好方法是,在Windows窗体中,你会说“从X1绘制一条线到Y1。然后从X2到Y2画一条线。然后……”。 每次需要“重绘”时重复此操作,因为屏幕无效。
相反,在WPF中,你说“我想要一条从X1到Y1的线。我想要一条从X2到Y2的线。” WPF然后决定何时以及如何为您绘制它。
这是通过将形状放在Canvas上,然后让WPF完成所有艰苦的工作来完成的。
当有太多的对象要快速绘制时(巨大的Visual Tree),另一种选择是使用WriteableBitmap
。 只需使用Pixels
属性设置像素和/或使用Render
方法绘制UIElements
。
我喜欢在这个例子中使用OnRender方法:
protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); drawingContext.DrawRectangle(null, new Pen(Brushes.Black, 2), new Rect(0, 0, ActualWidth, Height)); }
要在WPF中实现Draw循环类型行为,可以使用CompositionTarget.Rendering事件。 当WPF绘图系统绘制框架时,每帧提升一次。
正如其他人已经指出的那样,它不是非常友好的WPF,但是它可以用来从WPF应用程序中获得更直接的绘图行为。
在大多数情况下,您将使用单个根canvas并更新说出CompositionTarget.Rendering事件上元素的Canvas位置。
例如,要使整个屏幕上的椭圆形飞行,请执行以下操作:
在您的XAML中(对于大小为640 x 480的窗口):
在上面的XAML所在的Window背后的代码中(确保添加对System.Windows.Media的引用,以便查看CompsitionTarget对象:
public static Random rand = new Random(); public View() { InitializeComponent(); CompositionTarget.Rendering += CompositionTarget_Rendering; } void CompositionTarget_Rendering(object sender, System.EventArgs e) { double newLeft = rand.Next(0, 640); double newTop = rand.Next(0, 480); theEllipse.SetValue(Canvas.LeftProperty,newLeft); theEllipse.SetValue(Canvas.TopProperty, newTop); }
你应该添加一个canvas(或更改canvas的网格),然后绘制它。 这是微软在canvas上绘图
另外,我不知道你的这个问题有多相关,但你可能想看一下。