2012-12-27 36 views
9

मैं यह देखने के लिए एक परीक्षण प्रोग्राम बना रहा हूं कि मैं कस्टम तैयार सिस्टम में कितनी अच्छी तरह से ईवेंट जोड़ सकता हूं। Windows.Form.Control ऑब्जेक्ट। क्या मुझे इसके साथ अच्छा प्रदर्शन करना चाहिए, फिर मैं बाद में कुछ और उन्नत कर सकता हूं।विंडोज फॉर्म: ओवरलैपिंग नियंत्रणों को अनुमति देने का सही तरीका क्या है?

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

Wish that the two circles just overlapped properly instead of having the jutting corners.

ऊपर छवि से पता चलता है कि केंद्र सर्कल छोड़ दिया सर्कल द्वारा दफन है, लेकिन बाईं चक्र भी कोने ड्राइंग और उनके साथ केंद्र चक्र को कवर किया जाता है। मैं उन कोनों को छिपाने की उम्मीद कर रहा हूं, या कम से कम उन्हें पारदर्शी बना देता हूं। मैंने पढ़ा है कि make a control transparent का एक तरीका है, लेकिन बैककॉलर पर रंग। ट्रांसपैरेंट का उपयोग करके मुझे रंग पैनल के रंग से मेल खाने के बजाय कुछ कारणों से काला दे रहा था।

नीचे जीयूआई का कोड हिस्सा है (डिजाइनर शामिल नहीं है, लेकिन मुख्य भाग स्पष्ट होना चाहिए)।

namespace PaintingFirstAttempt 
{ 
    using System; 
    using System.Drawing; 
    using System.Windows.Forms; 

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

     private void BtnExit_Click(object sender, EventArgs e) 
     { 
      this.Close(); 
     } 

     private void BtnClear_Click(object sender, EventArgs e) 
     { 
      Graphics g1 = this.paintPanel.CreateGraphics(); 
      g1.Clear(this.paintPanel.BackColor); 
      g1.Dispose(); 
     } 

     private void PaintPanel_MouseDown(object sender, MouseEventArgs e) 
     { 
      this.paintPanel.Controls.Add(new EventableCircle { Location = new Point(e.X - 16, e.Y - 16), Size = new Size(32, 32) }); 
     } 
    } 
} 

नीचे कस्टम सर्कल है।

namespace PaintingFirstAttempt 
{ 
    using System; 
    using System.Drawing; 
    using System.Windows.Forms; 

    public class EventableCircle : Control 
    { 
     public EventableCircle() 
     { 
      this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
      // this.BackColor = Color.Transparent; 
     } 

     private static SolidBrush fillColor = new SolidBrush(Color.Red); 
     protected override void OnClick(EventArgs e) 
     { 
      MessageBox.Show("TODO: Bring up a combo box on right click."); 
     } 

     private void DrawCircle(Pen pen) 
     { 
      Graphics g = this.CreateGraphics(); 
      g.Clear(this.BackColor); 
      g.FillRectangle(new SolidBrush(Color.Transparent), 0, 0, 32, 32); 
      g.FillEllipse(fillColor, 0, 0, 32, 32); 
      g.DrawEllipse(pen, 0, 0, 32, 32); 
      g.Dispose(); 

     } 

     protected override void OnPaint(PaintEventArgs e) 
     { 
      this.DrawCircle(Pens.Black); 
     } 

     protected override void OnMouseEnter(EventArgs e) 
     { 
      base.OnMouseEnter(e); 
      this.DrawCircle(Pens.Blue); 
     } 

     protected override void OnMouseLeave(EventArgs e) 
     { 
      base.OnMouseLeave(e); 
      this.DrawCircle(Pens.Black); 
     } 
    } 
} 
मन में इस जानकारी के साथ

, मैं या तो हलकों के कोनों कैसे नहीं दिखाने के लिए, या इस को हल करने के लिए एक रास्ता मिल सकती है?

+1

यह मदद करनी चाहिए: http://www.c-sharpcorner.com/UploadFile/mahesh/DrawTransparentImageUsingAB10102005010514AM/DrawTransparentImageUsingAB.aspx - भी क्लिक और redrawing पता लगाने के लिए निर्देशांक की एक सूची रखने पर विचार 'नियंत्रण' –

+0

से प्राप्त करने के बजाय ग्राफ़िक ऑब्जेक्ट्स, मैं आपकी टिप्पणी जेरेमी के साथ कुछ समझ नहीं रहा हूं। सबसे पहले, क्या यह लिंक किसी छवि का उपयोग किए बिना भी काम करेगा? मैं अभी भी स्क्रैच से उत्पन्न करना चाहता हूं। दूसरा, निर्देशांक सूचीबद्ध करने का क्या फायदा है? क्या आप सुझाव दे रहे हैं कि जब मैं सर्कल में हूं तो मैं केवल गणना करता हूं? – Wolfman2000

+1

मुझे और स्पष्ट होना चाहिए था। मेमोरी में निर्देशांक की सूची का उपयोग करके लाल मंडल खींचना रेड-सर्किल उपयोगकर्ता नियंत्रणों का समूह बनाने से कहीं अधिक कुशल है। ऐसा प्रतीत होता है कि आपको केवल ग्राफिक ऑब्जेक्ट्स को पेंट करने की आवश्यकता है और फिर क्लिक ईवेंट पर पता लगाने और प्रतिक्रिया करने में सक्षम होना चाहिए। मुझे लगता है कि यह वह जगह है जहां समस्या भी है, वस्तुओं को आकर्षित करें क्योंकि नियंत्रण पारदर्शिता पर नियंत्रण खो देता है और यही कारण है कि मैं उन्हें ग्राफिक वस्तुओं के रूप में इलाज करने की सलाह देता हूं। आगे पढ़ने [रॉड स्टीफेंस के साथ सी # ग्राफिक प्रोग्रामिंग] (http://www.amazon.com/C- ग्राफिक्स- प्रोग्रामिंग- ebook/dp/B004GXC85W)। –

उत्तर

3

ठीक है बस एक मुख्य प्रारूप फॉर्म 1 में डालें, किसी भी कोड की आवश्यकता नहीं है। यहां उपयोगकर्ता नियंत्रण के लिए कोड है, फॉर्म पर 3 या 4 ड्रा करें ताकि वे दाईं ओर जाने पर ओवरलैप कर सकें।

फिर उन पर क्लिक करें! अक्षमताएं हैं, लेकिन बच्चे की रोना और मुझे जाना है, और यह आपके स्वयं के बनाए गए ऑब्जेक्ट संपादक को धड़कता है!

enter image description here

Public Class linectl 

    Public Sub DrawMe(ByVal g As Graphics, ByVal otherctl As Control) 
     Dim where As New Rectangle(otherctl.Left - Left, otherctl.Top - Top, otherctl.Width - 1, otherctl.Height - 1) 
     g.FillEllipse(Brushes.Red, where) 
     g.DrawEllipse(Pens.Black, where) 
    End Sub 

    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs) 
     MyBase.OnPaintBackground(e) 
     DrawMe(e.Graphics, Me) 
     drawneighbors() 
    End Sub 

    Private Sub linectl_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click 
     Me.Left += 10 
    End Sub 

    Private Sub linectl_MoveResize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move, Me.Resize 
     If Parent IsNot Nothing Then 
      For Each c In From ctl In Parent.Controls Where TypeOf ctl Is linectl Select CType(ctl, linectl) 
       Using g = c.CreateGraphics 
        g.Clear(c.BackColor) 
        c.DrawMe(g, c) 
        c.drawneighbors() 
       End Using 
      Next 
     End If 
    End Sub 

    Public Sub drawneighbors() 
     If Parent IsNot Nothing Then 
      Dim ctls = (From ctl In Parent.Controls Where TypeOf ctl Is linectl Let c = CType(ctl, linectl) _ 
         Select New With {.ctl = c, _ 
          .rect = New Rectangle(c.Left, c.Top, c.Width, c.Height)}).ToArray.Reverse 
      For Each ctl In ctls 
       Dim ctl_unclosed = ctl 
       For Each ictl In (From c In ctls Where ctl_unclosed.rect.IntersectsWith(c.rect)) 
        Using g = ictl.ctl.CreateGraphics 
         ictl.ctl.DrawMe(g, Me) 
        End Using 
        Using g = Me.CreateGraphics 
         Me.DrawMe(g, ictl.ctl) 
        End Using 
       Next 
      Next 
     End If 
    End Sub 

End Class