Laden...

Kommunikation zwischen Form und Usercontrol

Erstellt von chanderegg vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.823 Views
C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 15 Jahren
Kommunikation zwischen Form und Usercontrol

Hallo zusammen

Ich schreibe gerade ein Programm, in welchem der Aufbau einer Datenbank dargestellt wird. Ich habe auf der linken Seite einen Treeview erstellt, welcher die Struktur darstellt. (Projekt -> Version -> Tabelle -> Spalte)
Je nachdem welches Level ich auswähle, wird ein bestimmtes Usercontrol geöffnet.
Dies funktioniert alles soweit.

Nun möchte ich, dass dem Usercontrol mitgegeben wird, wie z.B. die Tabelle heisst. Dafür habe ich im Usercontrol Properties erstellt. Damit ich testen kann, ob dieser Wert weitergegeben wird habe ich im Usercontrol eine Textbox erstellt.

Ich habe es aber bisher nicht geschafft, dass dieser Wert angezeigt wird.
Kann mir jemand einen Tipp geben, was ich falsch mache?


private void Baumstruktur_AfterSelect(object sender, TreeViewEventArgs e)
        {

            if (e.Node.Level == 2)
            {
                tabellenAnsicht1.Visible = true;
                tabellenAnsicht1.tabellenname = e.Node.Text;
            }
         }

Mit diesen Befehlen mache ich das Usercontrol sichtbar und gebe den Wert mit


    public partial class TabellenAnsicht : UserControl
    {
        private String Tabellenname;
        private String Versionsname;
        private String Projektname;
        public String tabellenname
        {
            get { return Tabellenname; }
            set {Tabellenname = value;}
        }
        public String versionsname
        {
            get { return Versionsname; }
            set {Versionsname = value;}
        }
        public String projektname 
        {
            get {return Projektname;}
         }
        public TabellenAnsicht()
        {
            InitializeComponent();
            textBox1.Text = Tabellenname;
           
        }
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
           
        }
    }

Dies ist mein Usercontrol

Ich habe auch schon versucht die Textbox bei der Initialisation zu füllen. leider ohne Erfolg. Kann mir jemand einen Tipp geben?

3.511 Beiträge seit 2005
vor 15 Jahren

Du setzt den Wert von der Eigenschaft "Tabellenname" zwar in die Membervariable "tabellenname", aber danach passiert nichts mehr damit. Du musst den Text schon der TextBox zuweisen.

Wobei ich diesen Weg nicht gehen würde. Ich würde es so machen: Das TreeView bietet ein/mehrere Events an, wenn sich bestimmte Daten ändern. Das UserControl abonniert nur diese Events und wertet die Daten aus (die z.B. im EventArgs stehen). Somit sind diese beiden Komponenten entkoppelt und kannst diese ggf. zur jederzeit austauschen.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

R
158 Beiträge seit 2007
vor 15 Jahren

... Du musst den Text schon der TextBox zuweisen.... Das hat er schon gemacht, allerdings im Konstruktor (public TabellenAnsicht() )des UserControl 😉
NUR -> da isses falsch, weil das UserControl erst aufgebaut wird und somit Tabellenname NOCH leer ist...
Lösung: -> das LOAD-Event des UserControl abonieren:


private void TabellenAnsicht_Load ( object sender, EventArgs e)
{
textBox1.Text = Tabellenname;
}

Rainer

3.511 Beiträge seit 2005
vor 15 Jahren

Lösung: -> das LOAD-Event des UserControl abonieren:

Nö 🙂

Das bringt dir ja auch nichts, da zu dem Zeitpunkt die Variable ja immer noch leer ist. Die Textbox muss beim Zuweisen der Eigenschaft gefüllt werden.


private string tabellenname;

public string Tabellenname
{
  get { return tabellenname; }
  set
  {
    if (value != tabellenname)
    {
      tabellenname = value;
      textBox1.Text = tabellenname;
    }
  }
}

Aber wie gesagt, ist diese Vorgehensweise nicht Ideal. Man sollte hier unbedingt mit Events arbeiten.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 15 Jahren

Ich habe mir eure Vorschläge mal zu gemüte geführt.
Die Lösung von Khalid funktioniert ist aber wirklich nicht schön gelöst.

Wie das mit dem EventHandler geht ist mir noch nicht wirklich klar.
Ich werde nun mal nach weiteren Infos suche.

Vielen Dank für eure rasche Antwort

J
1.114 Beiträge seit 2007
vor 15 Jahren

Die Lösung von Khalid funktioniert ist aber wirklich nicht schön gelöst.

Was ist denn daran nicht schön. Nach aussen hin braucht dein Form NUR die Property zu kennen. Und egal, von wo sie geändert wird, so wird automatisch die TextBox mit aktualisiert.

Umgekehrt kannst du natürlich auch noch das Textchanged Event der Textbox nutzen, um manuelle Benutzereingaben auch gleich wieder in der Property TabellenName zu reflektieren.

Wie das mit dem EventHandler geht ist mir noch nicht wirklich klar.

von welchem EventHandler sprichst du?

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 15 Jahren

Ich habe nun die Lösung für mein Problem gefunden.

Am einfachsten und wohl auch am schönsten ist es, wenn man eine neue Methode erstellt, in welcher die Textbox ausgefüllt wird.


        private void Baumstruktur_AfterSelect(object sender, TreeViewEventArgs e)
        {

            if (e.Node.Level == 2)
            {
                tabellenAnsicht1.Visible = true;
                spaltenAnsicht1.Visible = false;
                tabellenAnsicht1.tabellenname = e.Node.Text;
                tabellenAnsicht1.TabellenAnsichtFelderFüllen();
            }

            if (e.Node.Level == 3)
            {
                tabellenAnsicht1.Visible = false;
                spaltenAnsicht1.Visible = true;
            }
            
        }

Danke für eure Hilfe

3.511 Beiträge seit 2005
vor 15 Jahren

von welchem EventHandler sprichst du?

Er meint wahrscheinlich das Verfahren, so wie ich es beschrieben habe. Das ganze über Events zu lösen, anstatt direkt dem UserControl alles hinzuschmeißen.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

5.299 Beiträge seit 2008
vor 15 Jahren

Am einfachsten und wohl auch am schönsten ist es, wenn man eine neue Methode erstellt, in welcher die Textbox ausgefüllt wird.

Das ist nicht nötig, bzw. redundant (=böse).
Dein Code braucht 2 öff. UserControl-Member, um tabellenname mitzugeben.
Der Code von TabellenAnsichtFelderFüllen() gehört einfach im Setter der tabellenname - Property ausgeführt.
tabellenname würde ich auch unbedingt groß schreiben, weil ist eine öff. Property (oder addressierst du da das Feld direkt (= auch böse 😉 ) )

Ich würde sogar das BackingField tabellenname ganz rauswerfen, und die Textbox.Text als Backingfield verwenden:


public partial class TabellenAnsicht : UserControl {
   private String _Versionsname;
   private String _Projektname;

   public TabellenAnsicht() {
      InitializeComponent();
      textBox1.Text = Tabellenname;

   }

   public String Tabellenname {
      get { return textBox1.Text; }
      set {
         textBox1.Text = value; 
      }
   }
   public String Versionsname {
      get { return _Versionsname; }
      set { _Versionsname = value; }
   }
   public String Projektname {
      get { return _Projektname; }
   }

   private void textBox1_TextChanged(object sender, EventArgs e) {

   }
}

Khalids Weg findich eher ungangbar. Da müsste man ja im UserControl Properties erstellen, mit denen man den Treeview hineinreicht, damit dessen Spezial-Events abonniert werden könnten.

Aber da das Form das UserControl kennt, läuft die Kommunikation Form->UserControl über Properties. Die Gegenrichtung, UserControl->Form, sollte allerdings schon über Events gehen, die das UC feuert, und das Form abonniert.

Der frühe Apfel fängt den Wurm.

J
1.114 Beiträge seit 2007
vor 15 Jahren

Er meint wahrscheinlich das Verfahren, so wie ich es beschrieben habe.

Achso.

Entkopplung ist immer gut 8), und dies insbesondere bei UserControls

R
158 Beiträge seit 2007
vor 15 Jahren

Lösung: -> das LOAD-Event des UserControl abonieren:
Nö 🙂

Das bringt dir ja auch nichts, da zu dem Zeitpunkt die Variable ja immer noch leer ist. ...

*räusper* und wieso funktioniert das bei mir mit der oben erwähnten Lösung ?( ?( ?( 8o 8o Die Variable ist sehrwohl schon zu diesem Zeitpunkt mit dem ihr zugewiesen Wert befüllt!

Ob nun diese Vorgehensweise ideal ist oder nicht - das bleibt jedem selbst überlassen - WAS ist bei C# bzw beim Programmieren schon ideal??
Und jedes Fitzelchen über Events (auch eigene) zu lösen - ich kann mich damit nicht anfreunden - aber wie gesagt: jeder hat seine Vorgehensweise zur Lösung eines Problems 8)
Rainer

J
1.114 Beiträge seit 2007
vor 15 Jahren

Und jedes Fitzelchen über Events (auch eigene) zu lösen - ich kann mich damit nicht anfreunden

Ich auch nicht, denn ich finde persönlich auch, dass das dann alles ziemlich schwierig wird, nachzuvollziehen was denn überhaupt passiert.

Aber bei gewissen Fällen sollte man UNBEDINGT auf Events bauen, und UserControls sind genau solch ein Fall. Denn ein UserControl ist dazu gedacht, auf einem Form abzulegen, und dann völlig autark zu arbeiten. Und wenn die Form Informationen aus dem UserControl benötigt, dann soll das UserControl dem Form diese Änderungen über Events mitteilen. Oder WANN sollst willst du dir diese Informationen vom Form aus holen. Denn der umgekehrte Weg geht nicht: Das UserControl kann nicht auf das Form zugreifen, und das ist auch gut so.

Der Ablauf ist ja immer folgender: Die Form setzt Properties der UserControl Instanz, und kann Methoden des UserControls aufrufen. Aber Rückgabewerte sollten immer vom UserControl via Events zurückgegeben werden. Denn dann ist es dem UserControl Schnuppe, wen diese Information interessiert.

5.299 Beiträge seit 2008
vor 15 Jahren

Entkopplung ist immer gut 8), und dies insbesondere bei UserControls

Hi!

Prinzipiell binnichja durchaus für Dogmen in der Programmiererei (wie: "Redundanz ist böse"), 
aber mein oberstes ist: "Man muß die Kirche auch mal im Dorf lassen können" ;)

Ansonsten wurde hier Entkoppelung erwähnt im Zusammenhang mit einem zusätzlichem Event, welches das UC abonnieren sollte, was eine zusätzliche Property erfordert, mit der dem UC der Sender mitgeteilt werden müsste.
Das ist doch eher eine Mehr-Verkoppelung denn eine Entkoppelung, und auch in die falsche Richtung, denn das UC sollte vom Form ja lieber gar nichts wissen.

Edit:

Aber Rückgabewerte sollten immer vom UserControl via Events zurückgegeben werden. Denn dann ist es dem UserControl Schnuppe, wen diese Information interessiert.

Habich was verpasst?
Hier gehts doch noch garnicht darum, wie das UC ggfs. Änderungen auffm Form auslöst, sondern nur, wie man sein "TabellenName" stetzt, und den zur Anzeige bringt.

Der frühe Apfel fängt den Wurm.

J
1.114 Beiträge seit 2007
vor 15 Jahren

Aber Rückgabewerte sollten immer vom UserControl via Events zurückgegeben werden. Denn dann ist es dem UserControl Schnuppe, wen diese Information interessiert.
Habich was verpasst?
Hier gehts doch noch garnicht darum, wie das UC ggfs. Änderungen auffm Form auslöst, sondern nur, wie man sein "TabellenName" stetzt, und den zur Anzeige bringt.

Das war eigentlich nur ne Erläuterung zu dem, was du selbst ja auch schon erwähnt hast. Nichts anderes hab ich ja damit sagen wollen.

Aber da das Form das UserControl kennt, läuft die Kommunikation Form->UserControl über Properties. Die Gegenrichtung, UserControl->Form, sollte allerdings schon über Events gehen, die das UC feuert, und das Form abonniert.

3.511 Beiträge seit 2005
vor 15 Jahren

*räusper* und wieso funktioniert das bei mir mit der oben erwähnten Lösung

Es geht hier darum, das die TextBox mit dem Wert aus der Eigenschaft "Tabellenname" gefüllt wird, wenn der Eigenschaft ein neuer Wert zugewiesen wird. Das wird definitiv nicht mit dem Load Ereignis funktionieren.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

5.299 Beiträge seit 2008
vor 15 Jahren

Hm, ich glaub, wir ham fleißig aneinander vorbeigeredet, euern letzten paar Beiträgen tätich jednfalls nur zustimmen X(

Jednfalls, @chanderegg:
Du kannst dir auch mal FramesetLike anschauen.
Also daß du deine UCs nicht dynamisch erzeugen, konfigurieren, positionieren, entsorgen musst, sondern den DesignKram an den UCs auf TabPages erledigst, die du zur Laufzeit über den NavigationFrame umschaltest.

Der frühe Apfel fängt den Wurm.

R
158 Beiträge seit 2007
vor 15 Jahren

@khalid:

...Je nachdem welches Level ich auswähle, wird ein bestimmtes Usercontrol geöffnet.... Diese Aussage hat mich dazu verleitet, meine 'OnLoad'-Lösung zu präsentieren 😉 weil: geöffnet_>heisst für mich, das UC wird neu erstellt...
Im nachhinein hab ich dann aber in seinen Codes gesehen, dass er die UserControls je nach Level un/sichtbar macht... dann geht natürlich die Load-Geschichte nicht mehr... Sorry für mein Missverständnis

@Jelly und die anderen:
selbstverständlich benutze ich bei den UC's selbstdefinierte Events, wenn das UC etwas zurückgeben soll bzw mit der aufrufenden Form kommunizieren will - da machen Events für mich Sinn... 😉

Rainer