2008-10-21 17 views
16

डब्ल्यूपीएफ पॉपअप नियंत्रण अच्छा है, लेकिन कुछ हद तक मेरी राय में सीमित है। जब इसे खोला जाता है तो पॉपअप को "ड्रैग" करने का कोई तरीका है (जैसे विंडोज़ के ड्रैगमोव() विधि के साथ)?डब्ल्यूपीएफ पॉपअप नियंत्रण

क्या यह बड़ी समस्याओं के बिना किया जा सकता है या क्या मुझे पॉपअप क्लास के लिए एक विकल्प लिखना है? धन्यवाद

उत्तर

13

यहां थंब का उपयोग करके एक सरल समाधान है। 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; 
     }; 
    } 
} 
+0

शायद मुझे कुछ आसान याद आ रहा है कि एक अनुभवी WPF डेवलपर को पता चलेगा, लेकिन यह फिर से उपयोग करने योग्य कैसे है? जब मैं एक अलग XAML संदर्भ में नियंत्रण लगाता हूं (जैसे कि इसे विंडो में पुन: उपयोग करने का प्रयास करना) कोई भी सामग्री जो मैं निर्दिष्ट करता हूं वह कैनवास तत्व को ओवरराइड करता है जिस पर अंगूठे बंधी होती है। – Vassi

+0

मैंने इस समाधान की कोशिश की है। बहुत अच्छा काम करता है! धन्यवाद जैकब। मुझे केवल एक मुद्दा का सामना करना पड़ रहा है: मेरे पास इस थंब के अंदर एक दृश्य है और मैं पूरे दृश्य को ठीक करने में सक्षम हूं, हालांकि यदि उस दृश्य में स्क्रॉलबार है, तो स्क्रॉलबार खींचने से अंगूठे को खींचने का कारण बन रहा है, और इसलिए संपूर्ण दृश्य। इससे बचने का कोई रास्ता है क्या? – Shankar

16

पॉपअप के लिए कोई ड्रैगमोव नहीं है। बस एक छोटा सा काम, इसमें बहुत सारे सुधार हैं जो आप इसमें जोड़ सकते हैं।

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

     } 
    } 
+16

** आउच **! नहीं, एक ['थंब'] (http://msdn.microsoft.com/en-us/library/ms749252%28VS.100%29.aspx) का उपयोग करें और इसके बजाय 'ड्रैगडेल्टा' ईवेंट (ऑप्ट। 'ड्रैगस्टार्ट'/यदि आप राज्यों को प्रबंधित करना चाहते हैं तो 'ड्रैग अपूर्ण')। यह बहुत अधिक कुशल है, स्मृति को खंडित नहीं करेगा और ऊपर दिए गए उदाहरण के रूप में माउस को खोने का जोखिम नहीं उठाएगा। इस तरह ड्रैगिंग ठीक से किया जाता है :) उदाहरण के लिए [यहां] (http://www.codeproject.com/KB/WPF/TubePlanner.aspx) देखें। – RedGlyph

+0

मैं मानता हूं कि मैंने जो समाधान दिया है वह सिर्फ एक हैक है, जैसा कि आपने कहा था कि DragDelta MoveMove से अधिक प्रदर्शनकारी है। –

+1

लेकिन अगर आप एक थंब के रूप में पॉपअप का दुरुपयोग नहीं करना चाहते हैं (जो मुझे लगता है कि मेरा मतलब रेडग्लिफ्स टिप्पणी में था), लेकिन एक और जटिल पॉपअप (जैसे वीडियो ओवरले) को स्थानांतरित करना चाहते हैं। एक स्पष्ट विंडो का उपयोग करना मेरे परिदृश्य में विकल्प नहीं है। –

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

यह मेरी खिड़की खींच लिए काम करता है जोड़ने के लिए, लेकिन जैसे कि यह अगर मैं उपवास रखने माउस को स्थानांतरित बताया गया था, यह पता मिलेगा खिड़की का और घटना को बढ़ाने बंद करो। ड्रैगिंग का उल्लेख किए बिना बिल्कुल आसान नहीं है। क्या कोई जानता है कि इसे ठीक से कैसे किया जाए, अच्छा और चिकनी खींचें, इसे बहुत खोले जाने पर इसे खोए बिना ??? यदि संभव हो तो एक साधारण उदाहरण पोस्ट करें, एक संपूर्ण ट्यूटोरियल के अलावा जो कोड में खोए गए मेरे जैसे शुरुआती लोगों को प्राप्त करेगा। धन्यवाद!

+0

जब आप खिड़की से बाहर निकलते हैं तो समस्या से बचने के लिए माउस को कैप्चर कर सकते हैं –

2

इसे प्राप्त करने का एक और तरीका है अपने पॉपअप की नियुक्ति को माउसपॉइंट पर सेट करना। इससे पॉपअप शुरू में माउस कर्सर की स्थिति में दिखाई देता है।

फिर आप पॉपअप के क्षैतिज ऑफसेट & वर्टिकलऑफसेट सेट करने के लिए या तो थंब या माउसमोव ईवेंट का उपयोग कर सकते हैं। ये गुण पॉपअप को अपनी मूल स्थिति से दूर स्थानांतरित करते हैं क्योंकि उपयोगकर्ता इसे ड्रैग करता है।

पॉपअप के अगले उपयोग के लिए क्षैतिज ऑफसेट और वर्टिकलऑफसेट को शून्य पर रीसेट करना याद रखें!

2

माउस खो के साथ इस मुद्दे जब भी तेजी से आगे बढ़,


हल किया जा सकता है इस MSDN से लिया जाता है:

नई विंडो बाल शामिल पॉपअप की सामग्री।

पॉपअप नियंत्रण एक लॉजिकल बच्चे के रूप में अपनी बाल सामग्री का संदर्भ रखता है। जब नई विंडो बनाई जाती है, तो पॉपअप की सामग्री विंडो का दृश्य बच्चा बन जाती है और पॉपअप का तार्किक बच्चा बनी हुई है। इसके विपरीत, पॉपअप अपनी बाल सामग्री का तार्किक अभिभावक बना हुआ है।


दूसरे शब्दों में, पॉपअप के बच्चे स्टैंडअलोन विंडो में प्रदर्शित किया जाता है।

तो निम्न की कोशिश करते समय:
Popup.CaptureMouse() रैपर विंडो को कैप्चर कर रहा है, न कि पॉपअप स्वयं। इसके बजाय Popup.Child.CaptureMouse() का उपयोग वास्तविक पॉपअप को कैप्चर करता है।

और अन्य सभी घटनाओं को Popup.Child का उपयोग करके पंजीकृत किया जाना चाहिए। Popup.Child.MouseMove, Popup.Child.LostCapture और इतने

पर यह परीक्षण किया गया है और पूरी तरह से ठीक काम करता है

तरह

+0

हां, माउस इनपुट को कैप्चर करना ड्रैगिंग को संभालने का सही तरीका है। यह सब e.Leftbutton == दबाया थोड़ा आलसी है और कुछ साइड इफेक्ट्स का कारण बनता है। – Alan

संबंधित मुद्दे