سؤال

يعد التحكم في WPF Popup رائعًا، ولكنه محدود إلى حد ما في رأيي.هل هناك طريقة "لسحب" نافذة منبثقة عند فتحها (كما هو الحال مع طريقة DragMove () للنوافذ)؟

هل يمكن القيام بذلك دون مشاكل كبيرة أم هل يجب أن أكتب بديلاً للفئة المنبثقة بنفسي؟شكرًا

هل كانت مفيدة؟

المحلول

وإليك حل بسيط باستخدام Thumb.

  • فئة فرعية منبثقة في 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;
        };
    }
}

نصائح أخرى

وليس هناك 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));

        }
    }

وهناك طريقة أخرى لتحقيق ذلك هو وضع وضع قافزة الخاص بك إلى MousePoint. وهذا ما يجعل منبثقة تظهر في البداية في موقف مؤشر الماوس.

وبعد ذلك يمكنك إما استخدام الإبهام أو الحدث MouseMove لضبط المنبثقة في HorizontalOffset وVerticalOffset. هذه الخصائص تحول قافزة بعيدا عن موقعها الأصلي كمستخدم تستمر عليه.

وحفظ لإعادة HorizontalOffset وVerticalOffset الى نقطة الصفر لاستخدام المقبل من منبثقة!

وهذه المسألة مع فقدان الماوس عندما تتحرك بسرعة كبيرة، لا يمكن حلها


ويؤخذ هذا من 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 الفرح الصورة، لقد وجدت قابل لاعادة الاستخدام الحل الذي يسمح لك بإضافة باعتباره الرقابة في 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