Перетащите элемент управления всплывающим окном WPF
Управление всплывающим окном WPF приятно, но, по моему мнению, несколько ограничено. есть способ "перетащить" всплывающее окно при его открытии (например, с помощью метода DragMove() для окон)?
Можно ли это сделать без больших проблем или мне нужно написать замену для всплывающего класса?
спасибо
Ответы
Ответ 1
Здесь простое решение с использованием Thumb.
- Подкласс Popup в XAML и codebehind
- Добавьте большой палец с шириной/высотой, установленным в 0 (это также можно сделать в XAML)
- Слушайте события MouseDown в Popup и поднимите одно и то же событие на Thumb
- Переместить всплывающее окно на DragDeltali >
XAML:
<Popup x:Class="PopupTest.DraggablePopup" ...>
<Canvas x:Name="ContentCanvas">
</Canvas>
</Popup>
С#:
public partial class DraggablePopup : Popup
{
public DraggablePopup()
{
var thumb = new Thumb
{
Width = 0,
Height = 0,
};
ContentCanvas.Children.Add(thumb);
MouseDown += (sender, e) =>
{
thumb.RaiseEvent(e);
};
thumb.DragDelta += (sender, e) =>
{
HorizontalOffset += e.HorizontalChange;
VerticalOffset += e.VerticalChange;
};
}
}
Ответ 2
Нет DragMove для PopUp. Просто небольшая работа вокруг, есть много улучшений, которые вы можете добавить к этому.
<Popup x:Name="pop" IsOpen="True" Height="200" Placement="AbsolutePoint" Width="200">
<Rectangle Stretch="Fill" Fill="Red"/>
</Popup>
В коде позади добавьте это событие mousemove
pop.MouseMove += new MouseEventHandler(pop_MouseMove);
void pop_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
pop.PlacementRectangle = new Rect(new Point(e.GetPosition(this).X,
e.GetPosition(this).Y),new Point(200,200));
}
}
Ответ 3
Другим способом достижения этого является установка вашего всплывающего размещения в MousePoint. Это делает всплывающее окно первоначально отображаемым в позиции курсора мыши.
Затем вы можете использовать событие Thumb или MouseMove для установки Popup HorizontalOffset и VerticalOffset. Эти свойства сдвигают Popup в исходное положение, когда пользователь тащит его.
Запомните reset HorizontalOffset и VerticalOffset до нуля для следующего использования всплывающего окна!
Ответ 4
Проблема с потерей мыши при слишком быстром перемещении может быть решена.
Это берется из msdn:
В новом окне содержится дочерний контент Popup.
Элемент Popup поддерживает ссылку на его дочернее содержимое как логическое дочернее. Когда создается новое окно, содержимое Popup становится визуальным дочерним элементом окна и остается логическим дочерним элементом Popup. И наоборот, Popup остается логическим родителем его дочернего содержимого.
Другими словами, дочерний элемент всплывающего окна отображается в автономном окне.
Поэтому, когда вы пытаетесь сделать следующее:
Popup.CaptureMouse()
захватывает окно обертки, а не всплывающее окно. Вместо этого использование Popup.Child.CaptureMouse()
фиксирует фактическое всплывающее окно.
И все остальные события должны быть зарегистрированы с помощью Popup.Child
.
Как Popup.Child.MouseMove
, Popup.Child.LostCapture
и т.д.
Это было протестировано и отлично работает
Ответ 5
Private Point startPoint;
private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(null);
}
private void Window_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point relative = e.GetPosition(null);
Point AbsolutePos = new Point(relative.X + this.Left, relative.Y + this.Top);
this.Top = AbsolutePos.Y - startPoint.Y;
this.Left = AbsolutePos.X - startPoint.X;
}
}
Это работает для перетаскивания моего окна, но, как мне было сказано, если я буду перемещать мышь быстро, он выйдет из окна и перестанет поднимать событие. Не говоря уже о том, что перетаскивание не является гладко. Кто-нибудь знает, как это сделать правильно, приятно и плавно перетаскивать, не теряя при перетаскивании слишком быстро??? Отправьте простой пример, если это возможно, за исключением целого учебника, в котором бы начинающие, как я потерял код. Спасибо!