Probleme mit DrawRectangle



  • Hi
    In meinem Projekt hab ich zwei Klassen A und B. In A deklariere ich zwei Variable und in B schreibe ich je einen Wert hinein. Nun möchte ich wiederum in A mit DrawRectangle die Variablen als x und y Koordinaten benutzen. In Debugg-Modus enthalten die Variablen den entsprechenden Wert, das Rechteck wird aber immer bei 0,0 gezeichnet und ich weiss nicht warum. Kann mir einer von euch sagen woran das liegen könnte?

    Danke



  • Vielleicht wäre etwas Code hilfreicher.



  • Kann ich machen

    Hier was in Programm A steht

    public float pic1_x = 0, pic1_y = 0;	
    public void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    		{
    			if (pic1_x != 0)
    			{
    
    				Pen RedPen= new Pen(Color.FromArgb(255,0,0),5); // Rot und 5 pixel breit 
    				Graphics graphic = pic_1.CreateGraphics(); 
    				graphic.DrawRectangle(RedPen, pic1_x, pic1_y, 5.0f, 5.0f); // zeichnet ein leeres rotes Rechteck
    			}
    		}
    

    Und in Progeramm B:

    protected override void OnMouseDown(MouseEventArgs e)
    		{
    			Form1 myForm1 = new Form1();
    			if (e.Button == MouseButtons.Left)
    			{
    
    				myForm1.pic1_x =  e.X;
    				myForm1.pic1_y = e.Y;
    				myForm1.Form1_Paint(this, null);
    			}
    
    		}
    


  • ziemlich rätselhaft ist, was du da machst.
    Bei jedem Mausklick wird eine neue Form erstellt, af der wird irgendwas gezeichnet. dumm ist nur, dass diese Form nie angezeigt wird.



  • Des versteh ich jetzt net ganz.
    Ich hab in beiden Klassen eine Form. Und soweit ich das verstanden hab muss ich doch in C#

    Form myForm = new Form();
    

    schreiben um auf eine Variable aus ner anderen Klasse zugreifen zu können.
    Was ich da mache ist ganz einfach, ich clicke auf die Form von A und lasse mir dann B anzeigen. Die Koordinaten die ich in B angeklickt habe möchte ich auf A übertragen. Beides in einem Fenster machen geht nicht.
    Wenn das ganze ein Anzeigeproblem ist, wie kann ich dann auf A zeichnen? muss ich das Fenster von A schließen und nach B wieder aufmachen?



  • wenn ich dich richtig verstehe, es muss in deiner Anwendung gleichzeitig zwei fenster offen sein. Fenster B in dem du klikst und Fenster A in dem bei jedem klick etwas gezeichnet werden soll.
    Das Vorgehen in so einem Fall wäre:

    in der Klasse FormB (Fenster 😎 deklarierst du eine globale (für die Klasse FormB) Variable von Type FormA.

    private FormA myForm;
    

    dann muss irgendwo diese Variable ein Wert bekommen. dass machst du z.B. in dem Konstruktor von FormB:

    myForm = new FormA();
    

    irgendwann muss myForm angezeigt werden, mit myForm.Show();
    wenn du jetzt bei einem Klick auf FormB auf der FormA zeichnen willst, brauchst du keine neue Variable (myForm1) sondern du zeichenst auf myForm:

    protected override void OnMouseDown(MouseEventArgs e)
     {
      if (e.Button == MouseButtons.Left)
      {
        myForm.pic1_x =  e.X;
        myForm.pic1_y = e.Y;
        myForm.Form1_Paint(this, null);
      }
    }
    

    Auf diese Weise funktioniert das mit mehreren Fenster in C#.

    bei deinem Code wird immer eine neue Instanz von Form1 erstellt, dann werden variablen zugewiesen und es wird dadrauf gezeichnet, das neue Fenster wird aber nicht angezeigt. (Show()).
    Aber das, was du siehst ist immer noch die erste erstelte Instance der Klasse Form1. und die hat immer noch pic1_x gleich 0 und pic1_y gleich 0, weil bei deinem MouseClick werden die überhaupt nicht berührt. Und das Rechteck wird dort gezeichnet nur, weil der Code dafür in der OnPaint() liegt. OnPaint wird immer automatisch aufgerufen, wenn Fenster gezeichent werden soll. und hat in dem Fall nix mit deinem
    myForm1.Form1_Paint(this, null);
    zu tun.

    Bei dir, wenn ich Rect habe, wird zuerst Form1 erzeugt. Die Form1 "erzeugt" irgendwann Form2, wo du klickst. Bei so einem Fall, muss du Form2 mitteilen, was ist Form1. Z.B.über eine public Variable.

    public class A
    {
      private B _b;
      public A()
      {
        _b = new B();
        _b.referenzzuA = this;
      }
    ...
      public void DoIt()
      {
      }
    }
    public class B
    {
      public A referenzzuA = null;
    ...
      private void IrgendWoClick()
      {
        if (referenzzuA != null)
        {
           referenzzuA.DoIt();
        }
      }
    }
    


  • Ich hab mal versucht das so wie du das beschreiben hast umzusetzen mit dem Erfolg, dass mein Speicher voll war und das Programm somit abgestürzt ist. Aber mit der Anzeige hängt das schon irgendwie zusammen weil ichs ausprobiert hab ein neues A-Fenster anzuzeigen und auf dem ist (allerdings erst nach verschiebung des Fensters) das Rechteck zu sehen. Aber ein neues Fenster öffnen will ich nicht und das mit dem verschieben ist auch nicht das wahre. Aber irgendwie muss das noch möglich sein, oder nicht?



  • Form1.cs

    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    
    namespace WindowsApplication1
    {
    	public class Form1 : System.Windows.Forms.Form
    	{
    		private System.ComponentModel.Container components = null;
    		public int p_x = 0;
    		public int p_y = 0;
    
    		public Form1()
    		{
    			InitializeComponent();
    		}
    
    		protected override void Dispose( bool disposing )
    		{
    			if( disposing )
    			{
    				if (components != null) 
    				{
    					components.Dispose();
    				}
    			}
    			base.Dispose( disposing );
    		}
    
    		#region Vom Windows Form-Designer generierter Code
    		private void InitializeComponent()
    		{
    			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
    			this.ClientSize = new System.Drawing.Size(292, 266);
    			this.Name = "Form1";
    			this.Text = "Form1";
    			this.Load += new System.EventHandler(this.Form1_Load);
    			this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
    
    		}
    		#endregion
    
    		[STAThread]
    		static void Main() 
    		{
    			Application.Run(new Form1());
    		}
    
    		private void Form1_Load(object sender, System.EventArgs e)
    		{
    			Form2 f = new Form2();
    			f.frm_Parent = this;
    			f.Show();
    		}
    
    		private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    		{
    			e.Graphics.DrawRectangle(Pens.Red, p_x, p_y, 5, 5);
    		}
    	}
    }
    

    Form2.cs

    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace WindowsApplication1
    {
    	public class Form2 : System.Windows.Forms.Form
    	{
    		public Form1 frm_Parent = null;
    
    		private System.ComponentModel.Container components = null;
    
    		public Form2()
    		{
    			InitializeComponent();
    		}
    
    		protected override void Dispose( bool disposing )
    		{
    			if( disposing )
    			{
    				if(components != null)
    				{
    					components.Dispose();
    				}
    			}
    			base.Dispose( disposing );
    		}
    
    		#region Vom Windows Form-Designer generierter Code
    		private void InitializeComponent()
    		{
    			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
    			this.ClientSize = new System.Drawing.Size(292, 266);
    			this.Name = "Form2";
    			this.Text = "Form2";
    			this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form2_MouseDown);
    
    		}
    		#endregion
    
    		private void Form2_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    		{
    			if (frm_Parent != null)
    			{
    				frm_Parent.p_x = e.X;
    				frm_Parent.p_y = e.Y;
    				frm_Parent.Invalidate();
    			}
    		}
    	}
    }
    

    Wenn du auf Form2 mit Maus klickst, wird in Form1 an der Position Rechteck gezeichnet



  • Danke jetzt gehts.

    wenn ich das richtig verstanden hab ists hauptsächlich an dem

    frm_Parent.Invalidate();
    

    gelegen. und das veranlast ein neuzeichnen der Form1.

    Danke


Anmelden zum Antworten