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?
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)
... 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
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)
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
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?
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
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)
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.
Er meint wahrscheinlich das Verfahren, so wie ich es beschrieben habe.
Achso.
Entkopplung ist immer gut 8), und dies insbesondere bei UserControls
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
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.
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.
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.
*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)
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.
@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