WinForms - WPF like painting

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; text-align:left
We know very well how easy is too create a WPF application where user can paint a rectangle using the mouse. To do this you just create a Rectangle control and set its coordinates, you dont worry about DoubleBuffering, repainting and such stuff. Well, Id
be very happy yo use WPF for the application where user can paint different shapes, but the clients insists to be a WinForms application. So the solution here is to use the XOR or ROP operation like in old good WinAPI years and I dont really like this. This
doesnt give me a nice option to move a text while in XOR mode.
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; text-align:left
So I was thinking how can I achieve same smooth painting experience in a WinForms application like Id have in WPF. Put together such a code, where I wanted to create a separate layer where Id paint the current shape, while leaving intact the rest of the objects.
I used same technique in an iPad application and worked pretty well.
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; text-align:left

<pre class="prettyprint 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
}
}
}[/code]
<br/>
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; text-align:left
which if course doesnt work as needed. Im getting a black panel when pressing the mouse instead of a transparent one. Plus the rectangle while is painted flickers a lot, even though I did set the DoubleBuffering stuff.
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; text-align:left
Can someone provide some better ideas of such an implementation or maybe there some other open source project where I can see how other people are doing. Id need to have same experience as in Paint.NET, just too bad is not open source anymore. (I know I can
use Reflector, and I did, but man, there is tons of code over there :) )
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; text-align:left
Thx for any ideas.
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; text-align:left


View the full article
 
Back
Top