Von einer Klasse auf die Form zugreifen

Von daher hab ich auch vorgeschlagen mal eine simple kleine Demo zu machen, wo Du das verhalten besser nachvollziehen kannst. Entweder Du machst mal selber eine, was für dich wohl eher besser währe, allein der Übung wegen. Ich wüsste nicht was das schaden könnte. :) Und/Oder ich mach mich heut Abend mal dran, das auch mit .NET 2.0 auszuprobieren.
 
So, ich bin jetzt doch endlich mal auf die gloreiche Idee gekommen das ganze mal zu debuggen.

Dabei ist mir aufgefallen, dass durch den Aufruf der Klasse mit "new" eine neue Klasse erzeugt wurde - logisch. Da diese Klasse von Form 1 abgeleitet ist, wurde damit gleichzeitig eine neue Form erzeugt - will ich nicht.
Diese Form hab ich dann anzeigen lassen und siehe da - der Button ist da. Nur wie kann ich das jetzt so hinbekommen, dass das alles auf einer Form geht?

Wenn ich das mit dem Vererben weglasse, dann kennt er die PictureBox wieder nicht....

Code:
//Aufruf der Klasse aus Form 1 heraus:
        private void button2_Click(object sender, EventArgs e)
        {
            CreateButtonClass test = new CreateButtonClass();
            test.Show();
        }
Code:
//Klasse:
    class CreateButtonClass : Form1
    {
        public CreateButtonClass()
        {
            Button btn = new Button();
            btn.Name = "TestButton";
            btn.Text = "TestButton";
            btn.Size = new Size(80, 40);
            btn.Location = new Point(5, 5);
            pictureBox.Controls.Add(btn);
            
        }
    }

Um die Vererbung auszuschließen, lösche ich also das rot markierte. Dann meckert er aber beim compilieren beim blau markiertem:
"PictureBox ist im aktuellen Context nicht vorhanden" --> logisch irgendwo.

Wie mache ich das nun richtig?
 
So, ich hägen dann mal hiermit das Demo-Projekt an.

Ein Freund hat mir davon abgeraten. Er kennt sich sehr gut mit Programmierung aus und meinte, dass unter anderem die GDI viel zu langsam für soetwas wäre...
 

Anhänge

  • Demo.zip
    32,5 KB · Aufrufe: 27
Danke für die Demo, so kann ich mir ein besseres Bild machen. Ich werde mir das mal anschauen. Aber am WE erst, für heute hab ich größeres Pensum vor mir.
Was dein Freund gemeint hatte, hat absolut gar nichts mit dem aktuellen Fall zu tuen. Wenn GDI+ angeblich bei C# zu langsam währe, dann frage ich mich, warum es sogar UML- und Photo-Editoren in C# gibt, die lediglich auf GDI+ basieren. ;)
 
Nein nein, das hast du falsch verstanden, bzw ich habe es falsch geschildert.

Also mein Vorhaben sollte so ein Nachbau werden:
http://novelconcepts.co.uk/FlashElementTD/

nur halt mit Multiplayermodus und einigen Erweiterungen. Die laufenden Einheiten wollte ich durch sich bewegende PictureBoxes lösen(hier: Vorübung mit Buttons). Und hier meint er hakt es. Finde ich auch verständlich, denn wenn es da 200 PictureBoxes gibt, dann kann ich mir das schon vorstellen.....
Wenn es 200 oder noch mehr FESTE Elemente wären, wäre das kein Problem, aber wenn die sich im Millisekunden takt bewegen, dann kann ich mir Probleme gut vorstellen.

Neuer Lösungsansatz: Direct3D - nur da bin ich noch mit dem Aufwand am gucken, ob sich das überhaupt lohnt?!
 
Ahh, jetzt kommen wir der Sache schon mal näher. :) So ein Spiel lässt sich nur in Direct 3D performant realisieren. Zu Direx3D hab ich einiges an guten Links. Nur habe ich sie nicht hier. Ich Poste sie demnächst. Dabei hast auch einige Spiele... :)
 
Zuletzt bearbeitet:
Managed DirectX Links

So hier die Belohnung für's warten. :D

[thread=269646]Managed DirectX - Linkliste[/thread]
 
Zuletzt bearbeitet:
Beispiel wie man von einer Klasse auf die Form zugreifen kann

So, ich hab mir nun auch deine Demo angeschaut. Bei Dir liegt nur ein kleines Verständnisproblem vor. :)

Du hast lediglich den Typ deines Forms Form1 deiner Helferklasse CreateButtonClass vererbt. Somit hast Du bei dem instanzieren deiner CreateButtonClass lediglich eine neue erweiterte Instanz von deinem Form1 erzeugt. Und daher ist auch in dem Form1 nichts passiert

Um nun auf die Objekte deines Form1 zugreifen zu können, benötigst Du eine Referenz auf die bereits vorhandene Instanz deines Form1. Die Referenz kannst Du auf verschiedene Arten bereit stellen.
  • Via Referenz im Konstruktor der CreateButtonClass, wenn sie permanent verwendet werden soll, sie quasi ständig im Programm benötigt wird.
C#:
internal class CreateButtonClass_Reference
{
    Form1 m_form1;
    Button m_newButton;

    public CreateButtonClass_Reference ( Form1 form1 )
    {
        this.m_form1 = form1;
    }

    public void CreateButton ()
    {
        this.m_newButton = new Button();
        this.m_newButton.Name = "TestButton";
        this.m_newButton.Text = "TestButton";
        this.m_newButton.Size = new Size( 80, 40 );
        this.m_newButton.Location = new Point( 5, 5 );
        this.m_newButton.Click += new EventHandler( m_button_Click );
        this.m_form1.pictureBox.Controls.Add( this.m_newButton );
    }

    void m_button_Click ( object sender, EventArgs e )
    {
        this.m_newButton.Dispose();
    }
}
  • Via Referenz einer statischen Methode oder Funktion die auf die PictureBox zugreifen soll.
C#:
internal class CreateButtonClass_Static
{
    public static void CreateButton ( PictureBox pictureBox, EventHandler eventHandler )
    {
        Button newButton = new Button();
        newButton.Name = "TestButton";
        newButton.Text = "TestButton";
        newButton.Size = new Size( 80, 40 );
        newButton.Location = new Point( 5, 5 );
        newButton.Click += new EventHandler( eventHandler );
        pictureBox.Controls.Add( newButton );
    }
}
  • Oder Du verwendest den Singelton Pattern um das Form zur Verfügung zu stellen. Das bietet sich an, wenn ein Objekt nur einmal benötigt wird aber ständig verwendet werden soll.
C#:
public partial class Form1 : Form
{
    #region Static Access

    static Form1 s_mainForm;

    public static Form1 GetInstance
    {
        get
        {
            if ( s_mainForm == null ) {
                lock ( typeof (Form1) ) {
                    s_mainForm = new Form1();
                }
            }
            return s_mainForm;
        }
    }

    #endregion

    Button m_newButton;
    CreateButtonClass_Reference m_createButtonClass_Reference;

    Form1 ()
    {
        InitializeComponent();
    }

    void createButtonButton_Click ( object sender, EventArgs e )
    {
        this.m_newButton = new Button();
        this.m_newButton.Name = "TestButton";
        this.m_newButton.Text = "TestButton";
        this.m_newButton.Size = new Size( 80, 40 );
        this.m_newButton.Location = new Point( 5, 5 );
        pictureBox.Controls.Add( this.m_newButton );
        this.m_newButton.Click += new EventHandler( this.newButton_Click );
    }

    void createButtonByReferenceButton_Click ( object sender, EventArgs e )
    {
        this.m_createButtonClass_Reference = new CreateButtonClass_Reference( this );
        this.m_createButtonClass_Reference.CreateButton();
    }

    void createButtonStaticButton_Click ( object sender, EventArgs e )
    {
        CreateButtonClass_Static.CreateButton( this.pictureBox, new EventHandler( this.newButton_Click ) );
    }

    void createButtonBySingletonButton_Click ( object sender, EventArgs e )
    {
        CreateButtonClass_Static.CreateButton( GetInstance.pictureBox, new EventHandler( this.newButton_Click ) );
    }

    void newButton_Click ( object sender, EventArgs e )
    {
        ((Control) sender).Dispose();
    }
}
 

Anhänge

  • Demo.zip
    73,7 KB · Aufrufe: 14
Zuletzt bearbeitet:
Zurück