문제

WPF 팝업 컨트롤은 훌륭하지만 제 생각에는 다소 제한적입니다. 팝업이 열릴 때 (Windows의 Dragmove () 메소드와 같이)를 "드래그"하는 방법이 있습니까?

이것은 큰 문제없이 수행 할 수 있습니까? 아니면 팝업 클래스를 직접 대체해야합니까? 감사해요

도움이 되었습니까?

해결책

다음은 엄지를 사용하는 간단한 솔루션입니다.

  • XAML 및 CodeBehind의 서브 클래스 팝업
  • 너비/높이가 0으로 설정된 엄지를 추가합니다 (XAML에서도 수행 할 수도 있음)
  • 팝업에서 Mousedown 이벤트를 듣고 엄지 손가락에서 같은 이벤트를 제기하십시오.
  • Dragdelta에서 팝업을 이동하십시오

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

다른 팁

팝업을위한 드래그 모브가 없습니다. 주변의 작은 작업만으로도 이것에 추가 할 수있는 많은 개선 사항이 있습니다.

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

        }
    }

이를 달성하는 또 다른 방법은 팝업의 배치를 MousePoint로 설정하는 것입니다. 이것은 팝업이 처음에 마우스 커서의 위치에 나타납니다.

그런 다음 Thumb 또는 MouseMove 이벤트를 사용하여 팝업의 HorizOntalOffset 및 verticalOffset을 설정할 수 있습니다. 이러한 속성은 사용자가 드래그 할 때 팝업을 원래 위치에서 멀어지게합니다.

다음으로 팝업을 사용하기 위해 HorizontalOffset 및 verticalOffset을 0으로 다시 재설정하십시오!

너무 빨리 움직일 때 마우스를 잃어버린 문제는 해결 될 수 있습니다.


이것은 MSDN에서 가져 왔습니다.

새 창에는 팝업의 자식 콘텐츠가 포함되어 있습니다.

팝업 컨트롤은 자녀의 콘텐츠에 대한 논리적 인 어린이로서의 참조를 유지합니다. 새 창이 만들어지면 팝업 내용은 창의 시각적 자녀가되어 논리적 인 팝업의 자식으로 남아 있습니다. 반대로, 팝업은 자식 콘텐츠의 논리적 부모로 남아 있습니다.


다시 말해, 팝업의 아이는 독립형 창에 표시됩니다.

그래서 다음을 시도 할 때 :
Popup.CaptureMouse() 팝업 자체가 아닌 래퍼 창을 캡처합니다. 대신 사용합니다 Popup.Child.CaptureMouse() 실제 팝업을 캡처합니다.

다른 모든 이벤트는 사용하여 등록해야합니다 Popup.Child.

처럼 Popup.Child.MouseMove, Popup.Child.LostCapture 등등

이것은 테스트되었으며 완벽하게 잘 작동합니다

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

이것은 내 창문을 끌어 내기 위해 작동하지만 마우스를 빨리 옮기면 말을 들었을 때 창 밖으로 나가 이벤트를 올릴 수 없습니다. 드래그를 언급하지 않고 전혀 매끄럽지 않습니다. 너무 빨리 드래그 할 때 잃어 버리지 않고 적절하게, 멋지고 부드러운 드래그하는 방법을 알고 있습니까 ??? 가능한 경우 간단한 예제를 게시하십시오. 가능한 경우 코드에서 나와 같은 초보자를 잃을 수있는 전체 튜토리얼을 제외하고. 감사!

구축 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;
        }
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top