Как нарисовать прямоугольник на MouseDown / Move c#
Я не совсем уверен, как нарисовать прямоугольник (не заполненный), когда я перетаскиваю mousedown при щелчке левой кнопкой мыши.
У меня это пока
private void canevas_MouseDown( object sender , MouseEventArgs e )
{
if( e.Button == MouseButtons.Left )
{
_topLeft = new Point( e.X , e.Y );
_drawing = true;
}
}
private void canevas_MouseMove( object sender , MouseEventArgs e )
{
if( _drawing )
{
Rectangle rec = new Rectangle( _topLeft.X , _topLeft.Y , ( e.X - _topLeft.X ) , ( e.Y - _topLeft.Y ) );
canevas.CreateGraphics().DrawRectangle( Pens.Black , rec );
}
}
но проблемы в том, что я не хочу, чтобы все прямоугольники отображались
4 ответов
некоторый код, чтобы пойти с правильным ответом Эда:
Point startPos; // mouse-down position
Point currentPos; // current mouse position
bool drawing; // busy drawing
List<Rectangle> rectangles = new List<Rectangle>(); // previous rectangles
private Rectangle getRectangle() {
return new Rectangle(
Math.Min(startPos.X, currentPos.X),
Math.Min(startPos.Y, currentPos.Y),
Math.Abs(startPos.X - currentPos.X),
Math.Abs(startPos.Y - currentPos.Y));
}
private void canevas_MouseDown(object sender, MouseEventArgs e) {
currentPos = startPos = e.Location;
drawing = true;
}
private void canevas_MouseMove(object sender, MouseEventArgs e) {
currentPos = e.Location;
if (drawing) canevas.Invalidate();
}
private void canevas_MouseUp(object sender, MouseEventArgs e) {
if (drawing) {
drawing = false;
var rc = getRectangle();
if (rc.Width > 0 && rc.Height > 0) rectangles.Add(rc);
canevas.Invalidate();
}
}
private void canevas_Paint(object sender, PaintEventArgs e) {
if (rectangles.Count > 0) e.Graphics.DrawRectangles(Pens.Black, rectangles.ToArray());
if (drawing) e.Graphics.DrawRectangle(Pens.Red, getRectangle());
}
чтобы получить "canevas" с включенной двойной буферизацией, чтобы картина не мерцала, используйте Project + Add New Item, выберите "Class" и вставьте этот код:
using System;
using System.Windows.Forms;
class Canvas : Panel {
public Canvas() {
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
}
компиляции. Перетащите новый элемент управления из верхней части панели инструментов в форму, заменив исходные "canevas". Соответствующим образом обновите обработчики событий.
не вызывайте CreateGraphics. В MouseDown сохраните начальную позицию и флаг, чтобы указать, что вы рисуете. В MouseMove проверьте флаг. Если вы рисуете, создайте прямоугольник относительно начальной позиции и сохраните его (что вы уже делаете), а затем вызовите Invalidate(). Весь ваш код чертежа будет находиться в OnPaint () (canvas.Краска из-за пределов класса, хотя я, вероятно, создал бы свой собственный класс для этого, чтобы избежать засорения вашего кода формы этим материалом).
рисование должно выполняться в обработчике краски (OnPaint). Если вы рисуете вне этого, ваш графический объект не очищается (следовательно, несколько прямоугольников), и все, что вы рисуете к нему, может/будет уничтожено в кажущееся нечетным время, когда ваше окно получает сообщение WM_PAINT.
EDIT: теперь, когда у вас возникли проблемы с производительностью, есть несколько простых способов немного оптимизировать картину. Во-первых, Invalidate будет необязательно принимать прямоугольник в качестве аргумента, поэтому что вам не нужно перекрашивать весь контроль. Во-вторых, если вы рисуете на MouseMove, вы будете рисовать совсем немного. Использование двойной буферизации также поможет, просто установите для свойства DoubleBuffered значение true или добавьте его в значение ControlStyles, вызвав SetStyle в элементе управления.
хорошо, теперь у меня есть это, его работа, но он мерцает много, даже с двойной буферизацией.
private void canevas_MouseDown( object sender , MouseEventArgs e )
{
_topLeft = new Point( e.X , e.Y );
if( e.Button == MouseButtons.Left )
{
_topLeft = new Point( e.X , e.Y );
_drawing = true;
}
}
private void canevas_MouseUp( object sender , MouseEventArgs e )
{
_drawing = false;
_bottomRight = new Point( e.X , e.Y );
int newX = _topLeft.X - (_bottomRight.X - _topLeft.X) / 2;
int newY =_topLeft.Y + (_bottomRight.Y - _topLeft.Y) / 2;
MouseEventArgs me = new MouseEventArgs( MouseButtons.Left , 1 , newX , newY , 0 );
canevas_MouseClick( canevas , me );
}
private void canevas_MouseMove( object sender , MouseEventArgs e )
{
if( _drawing )
{
_bottomRight = new Point( e.X , e.Y );
canevas.Invalidate();
}
}
а затем на paint
private void canevas_Paint( object sender , PaintEventArgs e )
{
Graphics g = canevas.CreateGraphics();
g.DrawImage( _buffer , new Rectangle( 0 , 0 , canevas.Width , canevas.Height ) );
g.DrawRectangle( Pens.White , new Rectangle( _topLeft.X , _topLeft.Y , ( _bottomRight.X - _topLeft.X ) , ( _bottomRight.Y - _topLeft.Y ) ) );
}
public Form1()
{
InitializeComponent();
// Use the cross "+" cursor
this.Cursor = System.Windows.Forms.Cursors.Cross;
// This will reduce flicker (Recommended)
this.DoubleBuffered = true;
}
добавьте этот код в вашу форму .это может уменьшить мерцание!