【发布时间】:2012-05-31 06:17:08
【问题描述】:
我们非常清楚创建一个 WPF 应用程序是多么容易,用户可以在其中使用鼠标绘制一个矩形。为此,您只需创建一个 Rectangle 控件并设置它的坐标,您不必担心 DoubleBuffering、重新绘制等。好吧,我很高兴您将 WPF 用于用户可以绘制不同形状的应用程序,但客户坚持使用 WinForms 应用程序。所以这里的解决方案是使用 XOR 或 ROP 操作,就像在旧的良好 WinAPI 年代一样,我不太喜欢这样。这并没有给我一个在 XOR 模式下移动文本的好选择。
所以我在想如何在 WinForms 应用程序中获得与在 WPF 中相同的流畅绘画体验。将这样的代码放在一起,我想在其中创建一个单独的图层,在其中绘制当前形状,同时保持其余对象不变。我在 iPad 应用程序中使用了相同的技术并且效果很好。
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace TestPainting
{
public partial class Form1 : Form
{
private bool _isMouseDown;
private Graphics _bufferGraphics;
private Point _startPos;
private TransparentPanel _paintBuffer;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
_isMouseDown = true;
_paintBuffer = new TransparentPanel
{
Size = Size,
};
Controls.Add(_paintBuffer);
_paintBuffer.BringToFront();
_bufferGraphics = Graphics.FromHwnd(_paintBuffer.Handle);
_startPos = e.Location;
Capture = true;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (!_isMouseDown)
return;
_bufferGraphics.Clear(Color.Transparent);
_bufferGraphics.DrawRectangle(Pens.Green, _startPos.X, _startPos.Y, e.X - _startPos.X, e.Y - _startPos.Y);
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
_isMouseDown = false;
Capture = false;
_bufferGraphics.Dispose();
Controls.Remove(_paintBuffer);
_paintBuffer.Dispose();
}
}
public class TransparentPanel : Panel
{
public TransparentPanel()
{
DoubleBuffered = true;
}
[Browsable(false)]
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// Do Nothing
}
}
}
如果课程不能按需要工作。按下鼠标而不是透明面板时,我得到一个黑色面板。加上绘制时的矩形闪烁很多,即使我确实设置了 DoubleBuffering 的东西。
有人可以提供一些关于这种实现的更好的想法,或者也许还有一些其他的开源项目,我可以看到其他人在做什么。我需要有与 Paint.NET 相同的经验,可惜不再是开源的了。 (我知道我可以使用 Reflector,而且我做到了,但是伙计,那里有大量代码 :))
感谢任何想法。
【问题讨论】:
-
是否可以通过 ElementHost 在 WinForms 应用程序中嵌入 WPF 内容?
-
甚至没有关闭。从现在开始,在我的所有项目中都禁止使用 WPF 这个词。 :)
-
我发现了这个:c-sharpcorner.com/uploadfile/chetanvnadgouda/…。也许会有所帮助。
-
更近一点,但它们在相同的表单上绘制而没有任何双缓冲,当用户使用鼠标绘制形状时,它们也会重新绘制所有形状。就我而言,我需要在用户绘画时保持其他图形不变。
-
这里我有一个小样本可以说明问题。我得到了所需的行为,但一切都很慢。示例网址:designleon.com/temp/TestPainting.zip
标签: wpf winforms double-buffering