Подскажите как правильно сделать контрол, который можно перетаскивать внутри контейнера. То есть как-то реализовать DragAndDrop? В msdn я не нашел, что можно реализовывать dragandrop — методы. Я сделал через
но на деле контрол вместе с панелью (на фоне которой — изображение) мерцает при перетаскивании. Что-то не так. Как реализовать правильно?? Подскажите, кто что знает.
Здравствуйте, rippi, Вы писали:
R>Привет,
R>Подскажите как правильно сделать контрол, который можно перетаскивать внутри контейнера. То есть как-то реализовать DragAndDrop? В msdn я не нашел, что можно реализовывать dragandrop — методы. Я сделал через
R> protected override void OnMouseDown( MouseEventArgs e ) R> { R> DownPoint = e.Location; R> IsDragMode = true; R> }
R> protected override void OnMouseUp( MouseEventArgs e ) R> { R> IsDragMode = false; R> }
R> protected override void OnMouseMove( MouseEventArgs e ) R> { R> if ( IsDragMode ) R> { R> Location = new Point( ( e.Location.X — DownPoint.X ) + Location.X, ( e.Location.Y — DownPoint.Y ) + Location.Y ); R> } R> }
R>но на деле контрол вместе с панелью (на фоне которой — изображение) мерцает при перетаскивании. Что-то не так. Как реализовать правильно?? Подскажите, кто что знает.
R>Спасибо, R>Евгений.
Как в MSDN нет Есть же куча свойств типа AllowDrop и ивентов DragDrop, DragEnter, DragLeave, DragOver
Так и будет мерцать! А чтоб не мерцало надо реальзовать ownerdraw. У тебя контейнер внутри которого ты таскаешь какого типа ?
кто здесь ?..
Re[2]: Сделать контрол, который можно перетаскивать.
R>>но на деле контрол вместе с панелью (на фоне которой — изображение) мерцает при перетаскивании. Что-то не так. Как реализовать правильно?? Подскажите, кто что знает.
R>>Спасибо, R>>Евгений.
AW>Как в MSDN нет Есть же куча свойств типа AllowDrop и ивентов DragDrop, DragEnter, DragLeave, DragOver
AW>Так и будет мерцать! А чтоб не мерцало надо реальзовать ownerdraw. У тебя контейнер внутри которого ты таскаешь какого типа ?
У меня контейнер типа Panel.
Re[3]: Сделать контрол, который можно перетаскивать.
Здравствуйте, rippi, Вы писали:
R>>>но на деле контрол вместе с панелью (на фоне которой — изображение) мерцает при перетаскивании. Что-то не так. Как реализовать правильно?? Подскажите, кто что знает.
R>>>Спасибо, R>>>Евгений.
AW>>Как в MSDN нет Есть же куча свойств типа AllowDrop и ивентов DragDrop, DragEnter, DragLeave, DragOver
AW>>Так и будет мерцать! А чтоб не мерцало надо реальзовать ownerdraw. У тебя контейнер внутри которого ты таскаешь какого типа ?
R>У меня контейнер типа Panel.
Самый простой способ для тебя — поменять на PictureBox. И задизайнить его как панель. Из плюсов — буферизованный вывод графики, а это то что надо чтоб не мерцало.
Второе место для устранения мерцания — это вызов руками метода Invalidate(Rectangle rect) в котором руками искать тот прямоугольник который надо обновить. а он как извесно меньше всего контрола. Например так.
protected override void OnMouseMove( MouseEventArgs e )
{
if ( IsDragMode )
{
Point p_old = Location;
Point p_new = new Point( ( e.Location.X — DownPoint.X ) + Location.X, ( e.Location.Y — DownPoint.Y ) + Location.Y );
Rectangle rect = new Rectangle(Math.Min(p_old.X, p_new.X), Math.Min(p_old.Y, p_new.Y), Math.Max(p_old.X, p_new.X)+Width, Math.Max(p_old.X, p_new.X)+Heigth);
Location = p_new;
Invalidate(rect);
}
}
И вообще, щас набросаю пример, попробую смоделировать более четко.
кто здесь ?..
Re: Сделать контрол, который можно перетаскивать.
От:
Аноним
Дата:
30.11.06 15:48
Оценка:
Если для перетаскивания чисто внутри контрола, то, например, так:
private Point currentMousePosition;
private void OnMouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
control.Capture = true;
currentMousePosition = control.PointToScreen(e.Location);
}
}
private void OnMouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point diff = CalculateDiff(e.Location);
SetControlLocation(diff);
control.Capture = false;
}
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
if (control.Capture)
{
Point diff = CalculateDiff(e.Location);
currentMousePosition = control.PointToScreen(e.Location);
SetControlLocation(diff);
}
}
private void SetControlLocation(Point diff)
{
control.Location = new Point(control.Location.X + diff.X, control.Location.Y + diff.Y);
}
private Point CalculateDiff(Point newPoint)
{
newPoint = control.PointToScreen(newPoint);
Point p = new Point(newPoint.X - currentMousePosition.X, newPoint.Y - currentMousePosition.Y);
return p;
}
Стоит так же добавить код, который будет обрабатывать случаи, когда курсор мыши вышел за пределы контейнера.
Re[4]: Сделать контрол, который можно перетаскивать.
AW>Никуда не дергается, никуда не бегает. "Не дымит, не пенится, не пригорает"(с) Масло какое-то
AW>В моем примере была панель, на которую я забросил Label. К нему прикрутил три евент хендлера и все.
Методы реализовал у панели на котором лежит Label?
Re[3]: Сделать контрол, который можно перетаскивать.
Я реализовал все именно так. Результат тот же.
У меня контейнер унаследован от Panel, на фоне лежит тяжелая картинка, около 2.5 мб. Свой контрол я унаследовал от Control. Это просто прозрачный прямоугольник.
R>Не понял, то есть эти обработчики реализуются в контейнере, а что такое control? R>Если это двигаемый объект, то как его получить?
Re[6]: Сделать контрол, который можно перетаскивать.
AW>>Никуда не дергается, никуда не бегает. "Не дымит, не пенится, не пригорает"(с) Масло какое-то
AW>>В моем примере была панель, на которую я забросил Label. К нему прикрутил три евент хендлера и все.
А>Методы реализовал у панели на котором лежит Label?
Ну если картинки на фоне нет, то у меня тоже не мерцает. Если на фоне тяжелая картинка, то появляется мерцание. Видимо перерисовывается вся картинка, короче неоптимально, достаточно перерисовать открывшиеся области.
Re[7]: Сделать контрол, который можно перетаскивать.
От:
Аноним
Дата:
01.12.06 10:56
Оценка:
Здравствуйте, rippi, Вы писали:
AW>>>Никуда не дергается, никуда не бегает. "Не дымит, не пенится, не пригорает"(с) Масло какое-то
AW>>>В моем примере была панель, на которую я забросил Label. К нему прикрутил три евент хендлера и все.
А>>Методы реализовал у панели на котором лежит Label?
R>Ну если картинки на фоне нет, то у меня тоже не мерцает. Если на фоне тяжелая картинка, то появляется мерцание. Видимо перерисовывается вся картинка, короче неоптимально, достаточно перерисовать открывшиеся области.
Лучше не использовать BackgroundImage свойство, а отрисовывать самостоятельно необходимые части изображения на котроле.
Re[3]: Сделать контрол, который можно перетаскивать.
От:
Аноним
Дата:
01.12.06 11:03
Оценка:
Здравствуйте, rippi, Вы писали:
R>Не понял, то есть эти обработчики реализуются в контейнере, а что такое control? R>Если это двигаемый объект, то как его получить?
Обработчики можно можно разместить как в контейнере, так и в коде вашего контрола, если вы создали дочерний класс от базового контрола.
control — это именно тот самый котнтрол. Можно в начале методов OnMouseDown, OnMouseUp, OnMouseMove добавить строку:
Control control = (Control)sender;
и в метод SetControlLocation добавить мараметр:
private void SetControlLocation(Control control, Point diff)
{
control.Location = new Point(control.Location.X + diff.X, control.Location.Y + diff.Y);
}
R>Здравствуйте, Аноним, Вы писали:
А>>Если для перетаскивания чисто внутри контрола, то, например, так:
А>>
здесь Canvas — это полотно контейнера (пока я не знаю как получить).
И это будет лучше? А может есть способ сразу в память скопировать блок изображения?
Re[4]: Сделать контрол, который можно перетаскивать.
А>Обработчики можно можно разместить как в контейнере, так и в коде вашего контрола, если вы создали дочерний класс от базового контрола.
А>control — это именно тот самый котнтрол. Можно в начале методов OnMouseDown, OnMouseUp, OnMouseMove добавить строку:
А>
А>Control control = (Control)sender;
А>
Понял, спасибо.
Хотя я все-таки расзместил обработчики в самом контроле.
Re[6]: Сделать контрол, который можно перетаскивать.
Здравствуйте, Аноним, Вы писали:
А>Методы реализовал у панели на котором лежит Label?
Методы реальзовал как EventHandler-ы для соответствующих эвентов класса Label
this.label1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.label1_MouseDown);
this.label1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.label1_MouseMove);
this.label1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.label1_MouseUp);
кто здесь ?..
Re[4]: Сделать контрол, который можно перетаскивать.
Здравствуйте, rippi, Вы писали:
AW>>А про Capture — это верно подмечено!
R>Я начинающий в .Net, а почему верно?
Потому что пока Capture == true контрол отлавливает любые мышиные евенты, даже если мышь вышла за пределы окна. Это спасает от багов, например еслы вытянуть контрол за окно и бросить его там, он потом будет за мышой бегать постоянно (во всяком случае у меня так воспроизводится)
кто здесь ?..
Re: Сделать контрол, который можно перетаскивать.
От:
Аноним
Дата:
01.12.06 12:28
Оценка:
Здравствуйте, rippi, Вы писали:
R>Привет,
R>Подскажите как правильно сделать контрол, который можно перетаскивать внутри контейнера. То есть как-то реализовать DragAndDrop? В msdn я не нашел, что можно реализовывать dragandrop — методы. Я сделал через
R>Спасибо, R>Евгений.
Посмотри у DevExpress XtraLayoutControl мне он понравился.