#c# #.net #winforms
#c# #.net #winforms
Вопрос:
У меня есть приложение, в котором пользователь рисует некоторые фигуры. Когда я нажимаю на фигуру и перетаскиваю ее, процессор загружается на 100% из-за Invalidate() внутри MouseMove. Если я использую таймер и вызываю Invalidate() из события tick, перемещение происходит не так гладко. Есть ли какой-либо другой подход для минимизации процессора и обеспечения плавного перемещения?
` Point startDragMousePoint;
Point startShapeLocation;
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if(isMouseDown)
{
Point deltaPoint = Point.Subtract(e.Location, new Size(startDragMousePoint));
shape.Location = Point.Add(startShapeLocation, new Size(deltaPoint));
Invalidate();
}
}
private void Canvas_Paint(object sender, PaintEventArgs e)
{
shape.Render(e.Graphics);
}`
Комментарии:
1. Что находится в методе «Invalidate»? не можете ли вы перенести логику в фоновый поток, используя класс Dispatcher, и установить для Dispatcherproperty некоторое меньшее значение?
2. в GDI Invalidate() заставляет окно перерисовываться. Это функция библиотеки Microsoft.
Ответ №1:
Есть три общих решения.
1) Не рисуйте во время перемещения, это долгое время было решением в Windows, когда вы перетаскивали окно, оно просто исчезало, и вы видели контур окна.
2) Создайте растровый объект и перемещайте только его. Обратите внимание, что вам придется перерисовать область под ним.
3) Не делайте недействительным окно отверстия, только область, которую вы изменяете. Рисование в буфере (растровое изображение) может помочь вам повторно использовать области.
Кроме того, если GDI не является самой быстрой функцией рисования в мире. Если ваша фигура очень сложная, вы можете рассмотреть возможность использования OpenGL, DirectX или SDL.
Ответ №2:
Вместо того, чтобы делать недействительной всю область, вы могли бы сделать недействительной часть элемента управления, которая была изменена, используя:
Rectangle changedArea = new Rectangle(cX, cY, cW, cH);
this.Invalidate(changedArea);
Также убедитесь, что ваш элемент управления настроен на использование двойной буферизации
this.DoubleBuffered = true;
Ответ №3:
Из ограниченного кода, который вы разместили, я думаю, что аннулирование не вызовет никаких проблем. Скорее всего, проблема может заключаться в реальном коде рендеринга вашей формы.Визуализация(). В прошлом я писал подобное приложение, в котором я вызывал Invalidate при перемещении мыши, и приложения работали нормально. Только было некоторое мерцание, которое исчезло при включении двойной буферизации.