2010-10-30 8 views
8

पर आयताकार को आकर्षित करने के लिए कैसे मुझे यकीन नहीं है कि जब मैं माउस पर क्लिक करते समय अपने मूसडाउन खींचता हूं तो आयताकार (भरे नहीं) को आकर्षित करने के लिए मुझे बिल्कुल यकीन नहीं है।माउसडाउन/मूव सी #

मैं इस अब तक

  private void canevas_MouseDown(object sender , MouseEventArgs e) 
      { 
        if(e.Button == MouseButtons.Left) 
        { 
          _topLeft = new Point(e.X , e.Y); 
          _drawing = true; 
        } 
      } 

      private void canevas_MouseMove(object sender , MouseEventArgs e) 
      { 
        if(_drawing) 
        { 
          Rectangle rec = new Rectangle(_topLeft.X , _topLeft.Y , (e.X - _topLeft.X) , (e.Y - _topLeft.Y)); 
          canevas.CreateGraphics().DrawRectangle(Pens.Black , rec); 
        } 
      } 

लेकिन समस्याओं यह है कि मैं न चाहते सभी आयतों

उत्तर

19

एड के सही जवाब के साथ जाने के कुछ कोड पर:

Point startPos;  // mouse-down position 
    Point currentPos; // current mouse position 
    bool drawing;  // busy drawing 
    List<Rectangle> rectangles = new List<Rectangle>(); // previous rectangles 

    private Rectangle getRectangle() { 
     return new Rectangle(
      Math.Min(startPos.X, currentPos.X), 
      Math.Min(startPos.Y, currentPos.Y), 
      Math.Abs(startPos.X - currentPos.X), 
      Math.Abs(startPos.Y - currentPos.Y)); 
    } 

    private void canevas_MouseDown(object sender, MouseEventArgs e) { 
     currentPos = startPos = e.Location; 
     drawing = true; 
    } 

    private void canevas_MouseMove(object sender, MouseEventArgs e) { 
     currentPos = e.Location; 
     if (drawing) canevas.Invalidate(); 
    } 

    private void canevas_MouseUp(object sender, MouseEventArgs e) { 
     if (drawing) { 
      drawing = false; 
      var rc = getRectangle(); 
      if (rc.Width > 0 && rc.Height > 0) rectangles.Add(rc); 
      canevas.Invalidate(); 
     } 
    } 

    private void canevas_Paint(object sender, PaintEventArgs e) { 
     if (rectangles.Count > 0) e.Graphics.DrawRectangles(Pens.Black, rectangles.ToArray()); 
     if (drawing) e.Graphics.DrawRectangle(Pens.Red, getRectangle()); 
    } 

एक 'canevas' कि डबल बफरिंग चालू की है, प्राप्त करने के लिए , इसलिए यह पेंटिंग झिलमिलाहट नहीं करता है, प्रोजेक्ट + नया आइटम जोड़ें, "क्लास" का चयन करें और इस कोड को पेस्ट करें:

using System; 
using System.Windows.Forms; 

class Canvas : Panel { 
    public Canvas() { 
     this.DoubleBuffered = true; 
     this.SetStyle(ControlStyles.ResizeRedraw, true); 
    } 
} 

संकलन। नए नियंत्रण को टूलबॉक्स के शीर्ष से अपने फॉर्म पर खींचें, मूल 'कैनवास' को बदल दें। तदनुसार ईवेंट हैंडलर अपडेट करें।

+1

धन्यवाद, मैंने इसे सही तरीके से किया था लेकिन इससे मुझे वापस खींचने वाले ड्रैग में मदद मिली। :) – Burnzy

+0

सबकुछ ठीक लगता है, झटके को छोड़कर, कोई विचार? – Burnzy

+0

मैंने एक टिप्पणी छोड़ दी, क्या आप पेंट इवेंट में ई। ग्राफिक्स का उपयोग कर रहे हैं? मैंने इस कोड का परीक्षण किया, यह डबल-बफरिंग के बिना भी झिलमिलाहट रहित है। –

5

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

ड्राइंग आपके पेंट हैंडलर (ऑनपेंट) में किया जाना चाहिए। यदि आप इसके बाहर आकर्षित करते हैं, तो आपकी ग्राफ़िक्स ऑब्जेक्ट को साफ़ नहीं किया जाता है (इसलिए एकाधिक आयताकार) और जो भी आप इसे आकर्षित करते हैं, उसे आपकी अजीब समय पर मिटा दिया जाएगा जब आपकी विंडो को WM_PAINT संदेश प्राप्त होता है।

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

+0

बीटीडब्ल्यू, मुझे यकीन नहीं है कि – Burnzy

+0

@ बर्नजी के लिए अमान्य है, अमान्येट नियंत्रण के ग्राफिक्स को अव्यवस्थित करता है ताकि पेंट ऑपरेशन को विंडोज़ द्वारा फिर से बुलाया जा सके। (मूल रूप से नियंत्रण को अमान्य करने के बाद इसे खुद को फिर से निकालना होगा) –

+0

किसी भी विचार को झटकेदार समस्या को ठीक करने का तरीका? – Burnzy

0

ठीक है अब मेरे पास यह है, यह काम कर रहा है, लेकिन यह दोहरी बफरिंग के साथ भी बहुत झटकेदार है।

  private void canevas_MouseDown(object sender , MouseEventArgs e) 
      { 
        _topLeft = new Point(e.X , e.Y); 
        if(e.Button == MouseButtons.Left) 
        { 
          _topLeft = new Point(e.X , e.Y); 
          _drawing = true; 
        } 
      } 

      private void canevas_MouseUp(object sender , MouseEventArgs e) 
      { 
        _drawing = false; 
        _bottomRight = new Point(e.X , e.Y); 
        int newX = _topLeft.X - (_bottomRight.X - _topLeft.X)/2; 
        int newY =_topLeft.Y + (_bottomRight.Y - _topLeft.Y)/2; 
        MouseEventArgs me = new MouseEventArgs(MouseButtons.Left , 1 , newX , newY , 0); 

        canevas_MouseClick(canevas , me); 
      } 

      private void canevas_MouseMove(object sender , MouseEventArgs e) 
      { 
        if(_drawing) 
        { 
          _bottomRight = new Point(e.X , e.Y); 
          canevas.Invalidate(); 
        } 
      } 

और फिर रंग

  private void canevas_Paint(object sender , PaintEventArgs e) 
      { 
        Graphics g = canevas.CreateGraphics(); 
        g.DrawImage(_buffer , new Rectangle(0 , 0 , canevas.Width , canevas.Height)); 
        g.DrawRectangle(Pens.White , new Rectangle(_topLeft.X , _topLeft.Y , (_bottomRight.X - _topLeft.X) , (_bottomRight.Y - _topLeft.Y))); 
      } 
+2

* * CreateGraphics() का उपयोग न करें। पेंट घटना में ई। ग्राफिक्स का प्रयोग करें। –

0
public Form1() 
    { 
     InitializeComponent(); 
     // Use the cross "+" cursor 
     this.Cursor = System.Windows.Forms.Cursors.Cross; 
     // This will reduce flicker (Recommended) 
     this.DoubleBuffered = true; 
    } 

इस कोड को अपने फॉर्म में जोड़ें। यह झटके को कम कर सकता है!