Is it possible to draw lines and figures like shown below in GDI+ and c#?
May be there is some way to do that in easy way in c#?
Update:
I mean that I need to imitate Hand-Drawing effect in GDI+
I would like to write something like:
graphics.DrawHandDrawnLine(Pens.Black, x1, y1, x2, y2);
and see something like this
I believe this will be hard to top in the 'more easy' department..:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Imaging;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace Doodle
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
List<Point> curPoints = new List<Point>();
List<List<Point>> allPoints = new List<List<Point>>();
private void pnlPaint_MouseDown(object sender, MouseEventArgs e)
{
if (curPoints.Count > 1)
{
// begin fresh line
curPoints.Clear();
// startpoint
curPoints.Add(e.Location);
}
}
private void pnlPaint_MouseUp(object sender, MouseEventArgs e)
{
if (curPoints.Count > 1)
{
// ToList creates a copy
allPoints.Add(curPoints.ToList());
curPoints.Clear();
}
}
private void pnlPaint_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
// here we should check if the distance is more than a minimum!
curPoints.Add(e.Location);
// let it show
pnlPaint.Invalidate();
}
private void pnlPaint_Paint(object sender, PaintEventArgs e)
{
using (Pen pen = new Pen(Color.Black, 3f))
{
// regular edges:
pen.MiterLimit = 1.5f
// current lines
if (curPoints.Count > 1) e.Graphics.DrawCurve(pen, curPoints.ToArray());
// other lines
foreach (List<Point> points in allPoints)
if (points.Count > 1) e.Graphics.DrawCurve(pen, points.ToArray());
}
}}
private void btn_undo_Click(object sender, EventArgs e)
{
if (allPoints.Count > 0)
{
allPoints.RemoveAt(allPoints.Count - 1);
pnlPaint.Invalidate();
}
}
private void btn_save_Click(object sender, EventArgs e)
{
string fileName = #"d:\sketch.png";
Bitmap bmp = new Bitmap(pnlPaint.ClientSize.Width, pnlPaint.ClientSize.Width);
pnlPaint.DrawToBitmap(bmp, pnlPaint.ClientRectangle);
bmp.Save(fileName, ImageFormat.Png);
}
}
class DrawPanel : Panel
{
public DrawPanel ()
{
DoubleBuffered = true;
}
}
}
Just add one DrawPanel and two Buttons..
(I really should have used my Wacom, and a little more space..)
Update: Instead of a Panel, which is a Container control and not really meant to draw onto you can use a Picturebox or a Label (with Autosize=false); both have the DoubleBuffered property turned on out of the box and support drawing better than Panels do.
I found this solution Creating a Hand-Drawn effect using .NET
Maybe there is something more easy, for example something with transformations?
Related
I'm trying to preview and resize shapes (just like you would do in Paint) before drawing them. The problem I encountered is that even though I'm using double buffering, I still get horrible flickering, which is a logical result of calling Invalidate() for the region containing the temporary element.
Another issue is that previewing lines using this method causes graphical residue to build up.
The shape also disappears when I stop moving the mouse, with the left mouse button still held down.
PaintForm.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace MyPaint
{
public partial class PaintForm : Form
{
// Where user clicks the first time.
private Point start = Point.Empty;
// Where user releases the mouse button.
private Point end = Point.Empty;
private DrawingElementType currentElementType = DrawingElementType.Line;
private List<DrawingElement> drawingElements;
// Used for double buffering (aka first drawing on a bitmap then drawing the bitmap onto the control).
private Bitmap bmp;
public PaintForm()
{
InitializeComponent();
drawingElements = new List<DrawingElement>();
bmp = new Bitmap(pbCanvas.Width, pbCanvas.Height, PixelFormat.Format24bppRgb);
Graphics.FromImage(bmp).Clear(Color.White);
}
private void pbCanvas_Paint(object sender, PaintEventArgs e)
{
if (bmp != null)
{
bmp.Dispose();
bmp = null;
}
bmp = new Bitmap(pbCanvas.Width, pbCanvas.Height, PixelFormat.Format24bppRgb);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
g.SmoothingMode = SmoothingMode.AntiAlias;
foreach (var elem in drawingElements)
{
switch (elem.Type)
{
case DrawingElementType.Line:
g.DrawLine(new Pen(Color.BlueViolet), elem.Start, elem.End);
break;
case DrawingElementType.Rectangle:
g.FillRectangle(Brushes.Black, elem.Container);
break;
case DrawingElementType.Ellipse:
g.FillEllipse(Brushes.Bisque, elem.Container);
break;
default:
break;
}
}
}
e.Graphics.DrawImageUnscaled(bmp, new Point(0, 0));
}
private void pbCanvas_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
start = e.Location;
}
}
private void pbCanvas_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
var temp = new DrawingElement(currentElementType, start, e.Location);
using (Graphics g = pbCanvas.CreateGraphics())
{
switch (currentElementType)
{
case DrawingElementType.Line:
g.DrawLine(new Pen(Color.BlueViolet), temp.Start, temp.End);
break;
case DrawingElementType.Rectangle:
g.FillRectangle(Brushes.Black, temp.Container);
break;
case DrawingElementType.Ellipse:
g.FillEllipse(Brushes.Bisque, temp.Container);
break;
default:
break;
}
}
pbCanvas.Invalidate(temp.Container);
}
}
private void pbCanvas_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
end = e.Location;
var elem = new DrawingElement(currentElementType, start, end);
drawingElements.Add(elem);
// This triggers the paint event and only repaints the region of the new element.
pbCanvas.Invalidate(elem.Container);
}
}
private void btnLine_Click(object sender, EventArgs e)
{
currentElementType = DrawingElementType.Line;
}
private void btnEllipse_Click(object sender, EventArgs e)
{
currentElementType = DrawingElementType.Ellipse;
}
private void btnlRectangle_Click(object sender, EventArgs e)
{
currentElementType = DrawingElementType.Rectangle;
}
}
}
DrawingElement.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyPaint
{
enum DrawingElementType
{
Line,
Rectangle,
Ellipse
}
class DrawingElement
{
public Point Start { get; set; }
public Point End { get; set; }
public DrawingElementType Type { get; }
// Returns the region of the control that contains the element.
public Rectangle Container
{
get
{
int width = Math.Abs(End.X - Start.X);
int height = Math.Abs(End.Y - Start.Y);
return new Rectangle(Math.Min(Start.X, End.X), Math.Min(Start.Y, End.Y), width, height);
}
}
public DrawingElement(DrawingElementType type, Point start, Point end)
{
Type = type;
Start = start;
End = end;
}
}
}
I probably fried my brain trying to find workarounds.
Preview of the application
I recently started programming in C# obviously and was trying to do a simple WinForms app that takes mouse coordinates and scales a Rectangle according to the coordinates.
The issue I am facing is that I don't know how to call a method that uses more arguments (in this case is x, y and PaintEventArgs). Or, I do know what to do with the PaintEvent.
Here is the whole code, since its pretty short and rather simple:
using System;
using System.Drawing;
using System.Windows.Forms;
public partial class Form1 : Form
{
public void Form1_MouseMove(object sender, MouseEventArgs e)
{
int x = e.X;
int y = e.Y;
String data = (x.ToString() + " " + y.ToString());
DrawRect(Something, x, y);
}
PaintEventArgs pEventArgs;
private void Form1_Paint(object sender, PaintEventArgs e)
{
}
public void DrawRect(PaintEventArgs e, int rey, int rex)
{
Graphics gr = e.Graphics;
Pen pen = new Pen(Color.Azure, 4);
Rectangle rect = new Rectangle(0, 0, rex, rey);
gr.DrawRectangle(pen, rect);
}
}
I'm trying to call the DrawRect() method to draw the Rectangle with width and height according to the mouse coordinates.
So how can I call the DrawRect() with coordinates and PaintEventArgs?
When drawing on a Control's surface, you always use the Paint event of that Control or override the OnPaint method of a Custom/User Control.
Do not try to store its Graphics object: it becomes invalid as soon as the Control is invalidated (repainted).
Use the Graphics object provided by the PaintEventArgs object.
When a more complex procedure is required to draw different shapes, you can pass the e.Graphics object to different methods which will use this object to perform specialized drawings.
In the example, the coordinates and other properties of each drawn shape are assigned to a specialized class, DrawingRectangle (a simplified structure here, it can hold more complex functionalities).
A List<DrawingRectangle>() stores the references of all the DrawingRectangle objects generated in a session (until the drawing is cleared).
Each time a Left MouseDown event is generated on the Control's surface, a new DrawingRectangle object is added to the List.
The e.Location is stored both as the DrawingRectangle.StartPoint (a value that doesn't change) and the DrawingRectangle.Location: this value will be updated when the mouse pointer is moved.
When the Mouse is moved, the current e.Location value is subtracted from the starting point coordinates previously stored. A simple calculation allows to draw the shapes from all sides.
This measure determines the current Size of the Rectangle.
To remove a Rectangle from the drawing, you just need to remove its reference from the List and Invalidate() the Control that provides the drawing surface.
To clear the drawing surface, clear the List<DrawingRectangle>() (drawingRects.Clear()) and call Invalidate().
Some other examples here:
Transparent Overlapping Circular Progress Bars
GraphicsPath and Matrix classes
Connecting different shapes
Drawing Transparent/Translucent Custom Controls
// Assign the Color used to draw the border of a shape to this Field
Color SelectedColor = Color.LightGreen;
List<DrawingRectangle> drawingRects = new List<DrawingRectangle>();
public class DrawingRectangle
{
public Rectangle Rect => new Rectangle(Location, Size);
public Size Size { get; set; }
public Point Location { get; set; }
public Control Owner { get; set; }
public Point StartPosition { get; set; }
public Color DrawingcColor { get; set; } = Color.LightGreen;
public float PenSize { get; set; } = 3f;
}
private void form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
DrawingRects.Add(new DrawingRectangle() {
Location = e.Location,
Size = Size.Empty,
StartPosition = e.Location,
Owner = (Control)sender,
DrawingcColor = SelectedColor // <= Shape's Border Color
});
}
private void form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
var dr = DrawingRects[DrawingRects.Count - 1];
if (e.Y < dr.StartPosition.Y) { dr.Location = new Point(dr.Rect.Location.X, e.Y); }
if (e.X < dr.StartPosition.X) { dr.Location = new Point(e.X, dr.Rect.Location.Y); }
dr.Size = new Size(Math.Abs(dr.StartPosition.X - e.X), Math.Abs(dr.StartPosition.Y - e.Y));
this.Invalidate();
}
private void form1_MouseUp(object sender, MouseEventArgs e)
{
// The last drawn shape
var dr = DrawingRects.Last();
// ListBox used to present the shape coordinates
lstPoints.Items.Add($"{dr.Location}, {dr.Size}");
}
private void form1_Paint(object sender, PaintEventArgs e)
{
DrawShapes(e.Graphics);
}
private void DrawShapes(Graphics g)
{
if (DrawingRects.Count == 0) return;
g.SmoothingMode = SmoothingMode.AntiAlias;
foreach (var dr in DrawingRects) {
using (Pen pen = new Pen(dr.DrawingcColor, dr.PenSize)) {
g.DrawRectangle(pen, dr.Rect);
};
}
}
// A Button used to save the current drawing to a Bitmap
private void btnSave_Click(object sender, EventArgs e)
{
using (var bitmap = new Bitmap(panCanvas.ClientRectangle.Width, panCanvas.ClientRectangle.Height))
using (var g = Graphics.FromImage(bitmap)) {
DrawShapes(g);
bitmap.Save(#"[Image Path]", ImageFormat.Png);
// Clone the Bitmap to show a thumbnail
}
}
// A Button used to clear the current drawing
private void btnClear_Click(object sender, EventArgs e)
{
drawingRects.Clear();
this.Invalidate();
}
app that takes mouse coordinates and scales rectangle according to the coordinates
I'd expect to see something like this (pseudocode):
Point _point;
void Form1_MouseMove(object sender, MouseEventArgs e)
{
... // calculate new coordinates/scale factor/whatever here
_point = ... ; // store results in fields
Invalidate(); // this will cause repaint every time you move mouse
}
void Form1_Paint(object sender, PaintEventArgs e)
{
... // take values from fields
e.Graphics.DrawRectangle(pen, rect); // draw
}
It's pretty simply. Painting is a combination of Invalidate() calls, which rise up paint event. The variables you pass using fields.
The PaintEventArgs allows you to access to the Graphics object, you need that one to draw something.
If you don't want to use the PaintEventArgs, i suggest that you call the CreateGraphics() method of your Form, and it will allow you to draw the rectangle.
To improve performance, i suggest that you use the using(...){ } keywork in order to dispose the Graphics object and the Pen object.
You need to include System.Drawing in order to use Graphics and Pen.
You're code will look like that :
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
Point _coordinates;
public Form1()
{
this._coordinates = new Point();
this.InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public void Form1_MouseMove(object sender, MouseEventArgs e)
{
this._coordinates = new Point(e.X, e.Y);
this.Invalidate();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
// Don't draw on first Paint event
if(this._coordinates.X != 0 && this._coordinates.Y != 0)
{
this.DrawRect(e);
}
}
public void DrawRect(PaintEventArgs e)
{
using (Pen pen = new Pen(Color.Azure, 4))
{
Rectangle rect = new Rectangle(0, 0, this._coordinates.X, this._coordinates.Y);
e.Graphics.DrawRectangle(pen, rect);
}
}
}
}
Drawing in WinForms application works in a slightly different way then you probably expect. Everything on screen now is considered to be temporary, if you e.g. minimize and restore your window, the onscreen stuff will be erased and you'll be asked to repaint it again (your window's Paint event will be fired by the system).
That's why that DrawRect method expects PaintEventArgs argument: it is supposed to be called only withing your Paint event handler. If you call it from outside (like it is suggested in other answer) your rectangles might behave inconsistently.
I would suggest remember your rectangles in some internal variable and then repaint them when asked for that by the system:
private Point pointToDrawRect = new Point(0,0);
public void Form1_MouseMove(object sender, MouseEventArgs e)
{
int x = e.X;
int y = e.Y;
String data = (x.ToString() + " " + y.ToString());
pointToDrawRect= new Point(x, y);
Invalidate();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if(pointToDrawRect.X != 0 || pointToDrawRect.Y != 0)
{
DrawRect(e, pointToDrawRect.X, pointToDrawRect.Y);
}
}
public void DrawRect(PaintEventArgs e, int rey, int rex)
{
using (Pen pen = new Pen(Color.Azure, 4))
{
Rectangle rect = new Rectangle(0, 0, rex, rey);
e.Graphics.DrawRectangle(pen, rect);
}
}
I am trying to set the starting point when the LMB is down and draw a line from the starting point to the current mouse position when the LMB is up, much like how MSPaint does it.
My problem is that I can't seem to get the line to appear on the picturebox when LMB is up. Can someone enlighten me please?
Edit:Sorry guys I realised the problem was elsewhere, but I learned a bunch of stuff in the process, thanks for all the input.
public partial class FormPaint : Form
{
Point? startPoint = Point.Empty;
Point? endPoint = Point.Empty;
bool isMouseDown = new Boolean();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (Control.MouseButtons == MouseButtons.Left)
{
startPoint = e.Location;
isMouseDown = true;
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
brush = new SolidBrush(color);
using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
g.DrawLine(new Pen(brush), startPoint.Value, endPoint.Value);
pictureBox1.Invalidate();
}
isMouseDown = false;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
endPoint = e.Location;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (brush = new SolidBrush(color))
{
e.Graphics.DrawLine(new Pen(brush, 5), startPoint.Value, endPoint.Value);
}
}
}
When you call Invalidate it forces the picture box to repaint. The problem is though that it discards everything you painted before. Then it calls the Paint on the picture box.
I would suggest to save the drawing data into a list and perform the painting inside the Paint event of the picture box using that saved data.
Also read How do I draw a circle and line in the picturebox?
Complete sample with line draw preview, enjoy.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinForm
{
public partial class frmMain : Form
{
/// <summary>
/// form constructor
/// </summary>
public frmMain()
{
InitializeComponent();
}
private PictureBox imgCanvas;
private bool isMouseDown;
private Point startPoint;
private Point currentPoint;
/// <summary>
/// form load
/// </summary>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
imgCanvas = new PictureBox
{
Location = new Point(8, 8),
Size = new Size(this.ClientSize.Width - 16, this.ClientSize.Height - 16),
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom,
BorderStyle = BorderStyle.Fixed3D,
};
imgCanvas.MouseDown += imgCanvas_MouseDown;
imgCanvas.MouseUp += imgCanvas_MouseUp;
imgCanvas.MouseMove += imgCanvas_MouseMove;
imgCanvas.Paint += imgCanvas_Paint;
this.Controls.Add(imgCanvas);
}
void imgCanvas_Paint(object sender, PaintEventArgs e)
{
if (isMouseDown)
{
e.Graphics.DrawLine(Pens.Red, startPoint, currentPoint);
}
}
void imgCanvas_MouseMove(object sender, MouseEventArgs e)
{
if (isMouseDown)
{
currentPoint = e.Location;
(sender as PictureBox).Refresh();
}
}
void imgCanvas_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isMouseDown = true;
startPoint = e.Location;
}
}
void imgCanvas_MouseUp(object sender, MouseEventArgs e)
{
if (isMouseDown)
{
if (e.Button == MouseButtons.Left)
{
isMouseDown = false;
PictureBox pb = sender as PictureBox;
// create image
if (pb.Image == null)
{
pb.Image = new Bitmap(pb.ClientSize.Width, pb.ClientSize.Height);
}
// draw
using (Graphics g = Graphics.FromImage(pb.Image))
{
g.DrawLine(Pens.Green, startPoint, e.Location);
pb.Refresh();
}
}
}
}
}
}
Result:
Hi I would do the selected area to cut an image on picturebox control.
I have the following code:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Rectangle rect;
private Pen p;
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (this.p == null)
this.p = new Pen(Color.FromArgb(100, 200, 200, 200), 5);
if (this.rect.Width > 0)
e.Graphics.DrawRectangle(this.p, this.rect);
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.X < this.rect.X)
{
this.rect.Width = this.rect.X - e.X;
this.rect.X = e.X;
}
else
{
this.rect.Width = e.X - this.rect.X;
}
if (e.Y < this.rect.Y)
{
this.rect.Height = this.rect.Y - e.Y;
this.rect.Y = e.Y;
}
else
{
this.rect.Height = e.Y - this.rect.Y;
}
this.Invalidate(this.rect);
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
this.rect.X = e.X;
this.rect.Y = e.Y;
}
}
}
It returns an error here:
Application.Run(new Form1());
Why?
thanks for all replies ;p
You shouldn't dispose of the Graphics object that is passed as part of the PaintEventArgs. That is probably what is causing your issue.
Try using this optimized code, if you still get error post it here (edit your original question) and we'll see.
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (this.p == nulll)
this.p = new Pen(Color.FromArgb(100, 200, 200, 200), 5);
if (this.rect.Width > 0)
e.Graphics.DrawRectangle(this.p, this.rect);
}
what is the error?
you are leaking Pen's. For every paint message you create a new pen and throw the old without disposing.
Off the top of my head I can't remember if you should dispose of the graphics object you get from the event args
Is there a way that one can make a control, such as a textbox, drag-droppable in C#?
I want the user to have the ability to click and hold the control with the mouse and drag it around on its surface and drop it anywhere within that surface.
Anyone has any idea how to implement this?
This answer helped me a lot. It's working great on any type of Control and Container.
If your control is moving within one container (e.g. panel), you can override OnMouseDown / OnMouseMove events, and adjust the Location property of the control.
Based on your question, it does not seem that you need full drag-and-drop (moving data between different controls or even applications).
if you're trying to drag an item from outside the silverlight container, then your best bet is to check out silverlight 4 beta
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
// wire up the various Drop events
InstallButton.Drop += new DragEventHandler(InstallButton_Drop);
InstallButton.DragOver += new DragEventHandler(InstallButton_DragOver);
InstallButton.DragEnter += new DragEventHandler(InstallButton_DragEnter);
InstallButton.DragLeave += new DragEventHandler(InstallButton_DragLeave);
}
void InstallButton_Drop(object sender, DragEventArgs e)
{
IDataObject foo = e.Data; // do something with data
}
This used to be so easy in VB6. But now we really only have what used to be called OleDrag.
Anyway, the following code should show you how. You just need a single label (dragDropLabel), and set the AllowDrop property of the form (DragDropTestForm) to True.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DragDropTest
{
public partial class DragDropTestForm : Form
{
// Negative offset to drop location, to adjust for position where a drag starts
// on a label.
private Point _labelOffset;
// Save the full type name for a label, since this is used to test for the control type.
private string labelTypeName = typeof(Label).FullName;
public DragDropTestForm()
{
InitializeComponent();
}
private void dragDropLabel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_labelOffset = new Point(-e.X, -e.Y);
}
}
private void dragDropLabel_MouseMove(object sender, MouseEventArgs e)
{
const double minimumDragDistance = 4;
const double minimumDragDistanceSquared = minimumDragDistance * minimumDragDistance;
if (e.Button == MouseButtons.Left)
{
// Minimum n pixel movement before drag starts.
if (((Math.Pow(_labelOffset.X - e.X, 2)) + Math.Pow(_labelOffset.Y - e.Y, 2)) >= minimumDragDistanceSquared)
{
dragDropLabel.DoDragDrop(dragDropLabel, DragDropEffects.Move);
}
}
}
private void DragDropTestForm_DragOver(object sender, DragEventArgs e)
{
IDataObject data = e.Data;
string[] formats = data.GetFormats();
if (formats[0] == labelTypeName)
{
e.Effect = DragDropEffects.Move;
}
}
private void DragDropTestForm_DragDrop(object sender, DragEventArgs e)
{
IDataObject data = e.Data;
string[] formats = data.GetFormats();
if (formats[0] == labelTypeName)
{
Label label = (Label) data.GetData(formats[0]);
if (label == dragDropLabel)
{
Point newLocation = new Point(e.X, e.Y);
newLocation.Offset(_labelOffset);
dragDropLabel.Location = this.PointToClient(newLocation);
}
}
}
}
}