Drag WPF Popup control - PullRequest
       9

Drag WPF Popup control

19 голосов
/ 21 октября 2008

Элемент управления WPF Popup хорош, но, на мой взгляд, несколько ограничен. Есть ли способ "перетащить" всплывающее окно вокруг, когда оно открывается (например, с помощью метода DragMove () окон)?

это можно сделать без особых проблем или мне нужно написать замену классу popup самостоятельно? спасибо

Ответы [ 6 ]

17 голосов
/ 21 октября 2008

DragMove для всплывающих окон отсутствует. Просто небольшая работа, есть много улучшений, которые вы можете добавить к этому.

<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));

        }
    }
14 голосов
/ 17 ноября 2011

Вот простое решение с использованием большого пальца.

  • Всплывающее окно подкласса в XAML и коде
  • Добавление большого пальца с шириной / высотой, установленной в 0 (это также может быть сделано в XAML)
  • Прослушивание событий MouseDown во всплывающем окне и создание того же события на большом пальце
  • Переместить всплывающее окно на DragDelta

XAML:

<Popup x:Class="PopupTest.DraggablePopup" ...>
    <Canvas x:Name="ContentCanvas">

    </Canvas>
</Popup>

C #:

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 голосов
/ 09 декабря 2011

Проблема с потерей мыши при слишком быстром перемещении может быть решена


Это взято из MSDN:

Новое окно содержит дочерний контент всплывающего окна.

Элемент управления Popup поддерживает ссылку на свой дочерний контент как логический дочерний элемент. Когда новое окно создано, содержимое Popup становится визуальным дочерним элементом окна и остается логическим дочерним элементом Popup. И наоборот, Popup остается логическим родителем своего дочернего содержимого.


Другими словами, дочерний элемент всплывающего окна отображается в отдельном окне.

Так что при попытке сделать следующее:
Popup.CaptureMouse() захватывает окно оболочки, а не само всплывающее окно. Вместо этого Popup.Child.CaptureMouse() фиксирует фактическое всплывающее окно.

И все остальные события должны быть зарегистрированы с использованием Popup.Child.

Как Popup.Child.MouseMove, Popup.Child.LostCapture и т. Д.

Это было проверено и прекрасно работает

2 голосов
/ 02 ноября 2011

Другим способом достижения этого является установка размещения вашего всплывающего окна в MousePoint. Это заставляет всплывающее окно изначально появляться в позиции курсора мыши.

Затем вы можете использовать событие Thumb или MouseMove, чтобы установить PopOupOptOffset & VerticalOffset. Эти свойства сдвигают всплывающее окно от его исходного положения, когда пользователь перетаскивает его.

Не забудьте сбросить HorizontalOffset и VerticalOffset обратно на ноль для следующего использования всплывающего окна!

0 голосов
/ 13 февраля 2019

Основываясь на ответе Jobi Joy , я нашел повторно используемое решение, которое позволяет вам добавлять в качестве элемента управления в xaml существующий элемент управления / страницу. Который было невозможно добавить как Xaml с Именем, так как он имеет другую область видимости.

    [ContentProperty("Child")]
    [DefaultEvent("Opened")]
    [DefaultProperty("Child")]
    [Localizability(LocalizationCategory.None)]
    public class DraggablePopup : Popup
    {
        public DraggablePopup()
        {
            MouseDown += (sender, e) =>
            {
                Thumb.RaiseEvent(e);
            };

            Thumb.DragDelta += (sender, e) =>
            {
                HorizontalOffset += e.HorizontalChange;
                VerticalOffset += e.VerticalChange;
            };
        }

        /// <summary>
        /// The original child added via Xaml
        /// </summary>
        public UIElement TrueChild { get; private set; }

        public Thumb Thumb { get; private set; } = new Thumb
        {
            Width = 0,
            Height = 0,
        };

        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);

            TrueChild = Child;

            var surrogateChild = new StackPanel();

            RemoveLogicalChild(TrueChild);

            surrogateChild.Children.Add(Thumb);
            surrogateChild.Children.Add(TrueChild);

            AddLogicalChild(surrogateChild);
            Child = surrogateChild;
        }
    }
0 голосов
/ 30 апреля 2011
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;
        }
    }

Это работает для перетаскивания моего окна, но, как было сказано, если я переместлю мышь быстро, оно выйдет из окна и перестанет вызывать событие. Без упоминания перетаскивания не совсем гладко. Кто-нибудь знает, как сделать это правильно, красиво и плавно перетаскивая, не теряя при перетаскивании слишком быстро ??? Если возможно, опубликуйте простой пример, за исключением целого учебника, в котором начинающие, как я, потеряли в коде. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...