2008-08-26 9 views
15

क्या यह सुनिश्चित करने का कोई आसान तरीका है कि ड्रैग-एंड-ड्रॉप पूरा होने में विफल होने के बाद, माउसअप ईवेंट को ढांचे से नहीं खाया जाता है और अनदेखा नहीं किया जाता है?DoDragDrop और MouseUp

मुझे one mechanism का वर्णन करने वाला एक ब्लॉग पोस्ट मिला है, लेकिन इसमें स्टेटस फ्लैग, माउसमोव इवेंट्स, मैनुअल "माउस छोड़" चेकिंग इत्यादि सहित मैन्युअल बहीखाता का एक अच्छा सौदा शामिल है, जिनमें से सभी को लागू करने की आवश्यकता नहीं है इसे टाला जा सकता है।

+0

argh, मैंने भी इस समस्या में भाग लिया है। अगर तुम मुझसे पूछो तो बहुत परेशान! –

उत्तर

20

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

एक त्वरित पक्ष नोट पर, इस तरह की समस्याओं के लिए यदि आप कुछ कोड प्रदान करते हैं तो यह बहुत अच्छा होगा ताकि हम देख सकें कि आप क्या करने की कोशिश कर रहे हैं। मैं यह इसलिए कहता हूं क्योंकि मैंने अपने समाधान में आपके कोड के बारे में कुछ चीजें मान ली हैं ... इसलिए उम्मीद है कि यह बहुत करीब है।

यहाँ कोड है, जो मैं नीचे की व्याख्या करेगा है:

this.LabelDrag.QueryContinueDrag += new System.Windows.Forms.QueryContinueDragEventHandler(this.LabelDrag_QueryContinueDrag); 
this.LabelDrag.MouseDown += new System.Windows.Forms.MouseEventHandler(this.LabelDrag_MouseDown); 
this.LabelDrag.MouseUp += new System.Windows.Forms.MouseEventHandler(this.LabelDrag_MouseUp); 

this.LabelDrop.DragDrop += new System.Windows.Forms.DragEventHandler(this.LabelDrop_DragDrop); 
this.LabelDrop.DragEnter += new System.Windows.Forms.DragEventHandler(this.LabelMain_DragEnter); 

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void LabelDrop_DragDrop(object sender, DragEventArgs e) 
    { 
     LabelDrop.Text = e.Data.GetData(DataFormats.Text).ToString(); 
    } 


    private void LabelMain_DragEnter(object sender, DragEventArgs e) 
    { 
     if (e.Data.GetDataPresent(DataFormats.Text)) 
      e.Effect = DragDropEffects.Copy; 
     else 
      e.Effect = DragDropEffects.None; 

    } 

    private void LabelDrag_MouseDown(object sender, MouseEventArgs e) 
    { 
     //EXTREMELY IMPORTANT - MUST CALL LabelDrag's DoDragDrop method!! 
     //Calling the Form's DoDragDrop WILL NOT allow QueryContinueDrag to fire! 
     ((Label)sender).DoDragDrop(TextMain.Text, DragDropEffects.Copy); 
    } 

    private void LabelDrag_MouseUp(object sender, MouseEventArgs e) 
    { 
     LabelDrop.Text = "LabelDrag_MouseUp"; 
    } 

    private void LabelDrag_QueryContinueDrag(object sender, QueryContinueDragEventArgs e) 
    { 
     //Get rect of LabelDrop 
     Rectangle rect = new Rectangle(LabelDrop.Location, new Size(LabelDrop.Width, LabelDrop.Height)); 

     //If the left mouse button is up and the mouse is not currently over LabelDrop 
     if (Control.MouseButtons != MouseButtons.Left && !rect.Contains(PointToClient(Control.MousePosition))) 
     { 
      //Cancel the DragDrop Action 
      e.Action = DragAction.Cancel; 
      //Manually fire the MouseUp event 
      LabelDrag_MouseUp(sender, new MouseEventArgs(Control.MouseButtons, 0, Control.MousePosition.X, Control.MousePosition.Y, 0)); 
     } 
    } 

} 

मैं डिजाइनर कोड के सबसे बाहर छोड़ दिया है, लेकिन कोड इवेंट हैंडलर लिंक शामिल ताकि आप सुनिश्चित क्या क्या से जुड़ा हुआ है हो सकता है। मेरे उदाहरण में, लेबल ड्रैग और लेबलड्रॉप लेबल के बीच ड्रैग/ड्रॉप हो रहा है।

मेरे समाधान का मुख्य भाग QueryContinueDrag ईवेंट का उपयोग कर रहा है। यह घटना तब होती है जब उस नियंत्रण पर DoDragDrop को कॉल करने के बाद कीबोर्ड या माउस स्थिति बदल जाती है। आप पहले से ही ऐसा कर रहे हैं, लेकिन यह बहुत महत्वपूर्ण है कि आप नियंत्रण के DoDragDrop विधि को कॉल करें जो आपका स्रोत है और फ़ॉर्म से जुड़ी विधि नहीं है। अन्यथा QueryContinueDrag आग नहीं होगा!

ध्यान देने योग्य एक बात यह है कि जब आप माउस को ड्रॉप कंट्रोल पर माउस छोड़ते हैं तो हमें वास्तव में आग लग जाएगी, इसलिए हमें यह सुनिश्चित करने की आवश्यकता है कि हम इसके लिए अनुमति दें। यह जांच कर संभाला जाता है कि माउस स्थिति (ग्लोबल कंट्रोल.माउसपोज़शन प्रॉपर्टी के साथ पुनर्प्राप्त) लेबलड्रॉप कंट्रोल आयत के अंदर है। आपको माउसपॉज़िशन को क्लाइंट विंडो के सापेक्ष पॉइंट टू क्लाइंट के साथ एक बिंदु पर कन्वर्ट करने के लिए भी सुनिश्चित करना होगा। MousePosition स्क्रीन रिश्तेदार स्थिति देता है।

तो जाँच है कि माउस ड्रॉप नियंत्रण अपने हाथ में नहीं है द्वारा और उस माउस बटन अब अप हम प्रभावी रूप से LabelDrag नियंत्रण के लिए एक MouseUp घटना पर कब्जा कर लिया है! :) अब, आप जो भी प्रसंस्करण यहां करना चाहते हैं वह कर सकते हैं, लेकिन यदि आपके पास पहले से ही कोड है जिसे आप माउसअप इवेंट हैंडलर में उपयोग कर रहे हैं, तो यह कुशल नहीं है। तो बस अपने माउसअप ईवेंट को यहां से कॉल करें, इसे आवश्यक पैरामीटर पास करें और माउसअप हैंडलर को कभी भी अंतर नहीं पता होगा।

बस एक नोट यद्यपि, जैसा कि मैंने DoDragDrop से भीतर MouseDown ईवेंट हैंडलर मेरे उदाहरण में कहते हैं, इस कोड वास्तव में आग एक सीधा MouseUp घटना हो कभी नहीं करना चाहिए करने के लिए। मैंने यह कोड दिखाने के लिए बस उस कोड को रखा है कि ऐसा करना संभव है।

आशा है कि मदद करता है!

+0

आपके समाधान से बहुत कुछ सीखा! धन्यवाद! –

+1

आपको विचार बहुत अच्छा है, धन्यवाद!लेकिन मुझे लगता है कि आपका कथन कथन जैसा दिखना चाहिए (बटन फॉर्म के अलावा किसी अन्य चीज़ में हो सकता है, नकली से छुटकारा नहीं मिला): अगर (Control.MouseButtons! = MouseButtons.Left && rect.Contains (button.Parent.PointToClient (नियंत्रण .MousePosition)) – colithium

+0

'// बेहद महत्वपूर्ण - लेबल ड्रैग की DoDragDrop विधि को कॉल करना चाहिए !! 'बहुत बहुत धन्यवाद! घंटों के लिए इसे समझने की कोशिश कर रहे थे। – Dan

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