Splitter - Benennung der Container und Zugriff auf Controls

  • VB.NET

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Splitter - Benennung der Container und Zugriff auf Controls

    Moin!

    ich bin mal wieder am ausproblieren und nun dachte ich mir noch einen SplitterContainer zu verwenden.

    Hier erst einmal ein Bild vom Dialog - hatte allerdings erst alles lauffähig und dann den SC eingebaut.



    Hinter der Verzeichnisauswahl hatte ich als Zugriff auf die TextBox folgende Codezeile erstellt:

    VB.NET-Quellcode

    1. Dim StatusBild As Windows.Forms.PictureBox = Me.Controls("pb_folder_" & Idx.ToString)


    Aber irgendwie klappt das jetzt nicht mehr! Vermutlich muss ich irgendwie die Panels dazwischen hängen. Aber wieder wird dieses nicht bei der automatischen Codegenerierung vorgenommen, wenn ich einen Doppelklick auf den Button mache?!?!?

    Das wäre die eine Frage. Nun habe ich zunächst einen SC mit vertikaler Trennung und dann in den oberen Teil einen mit horizontaler Trennung eingefügt. Kann ich irgendwie die SC direkt greifen um diese noch entsprechend zu benennen? Irgendwie komme ich immer nur an die SC-Panels ran.

    Gruß Jan

    jan99 schrieb:

    Kann ich irgendwie die SC direkt greifen um diese noch entsprechend zu benennen? Irgendwie komme ich immer nur an die SC-Panels ran.
    Mit Strg + Alt + T kannst du die Dokumentengliederung deiner Form aufrufen und dort ganz bequem in deiner Controls-Hierarchie navigieren...
    Dann siehst du auch, welche Controls sich in welche Container befinden und wie du da per Code rankommst...
    Hallo Jan
    Zu 1.
    Entweder gibst du den ganzen Pfad an, oder du verwendest die Control.ControlCollection.Find(String, Boolean)
    Method
    . Den ganze Pfad zum Control kannst du in der Dokumentgliederung sehen.

    Zu 2.
    da gibt es mehrere Möglichkeiten
    1. RMT auf SC-Panel -> Splitcontaner auswählen
    2. Im Eigenschaftenfenster im Pulldown
    3. In der Dokumentgliederung

    Gruss HenryV
    Moin!

    Danke erst einmal für die Hilfestellung.

    Den Zugriff auf die Control des SC habe ich hinbekommen.

    Nun wollte ich ja noch auf die Controls zugereifen.

    Bisher hatte ich das ohne die SC so definiert:

    VB.NET-Quellcode

    1. Dim TBox As Windows.Forms.TextBox = Me.Controls("tb_folder_" & Idx.ToString)


    Nun muss ich ja über den SC und das Panel gehen. Nun passt es mit der Nummer des Panels und den anderen Indizies und deshalb dachte ich so weiter zu kommen:

    VB.NET-Quellcode

    1. Dim SC As Windows.Forms.SplitContainer = Me.Controls("SC_Horizontal")
    2. Dim TBox As Windows.Forms.TextBox = SC.Panel1.Controls("tb_folder_" & Idx.ToString)


    Aber leider daneben!

    Kann mir einer weiterhelfen bei dem Zugriff - das "i"-Tüpfelchen wäre jetzt noch, wenn die Nummer aus der Panelbezeichnung auch noch durch Idx ersetzt werden kann.

    Bin wirklich gespannt, weil mit dem Latein am Ende.

    Gruß Jan


    Manuell habe ich das hinbekommen:

    VB.NET-Quellcode

    @jan99 Pack im Designer da ein Control rein und sieh Dir im Designercode an, wie dieses Control angesprochen wird.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Moin!

    ich dachte sofort ich wüsste was Du meinst. Habe in die form1.designer.vb geschaut und für tb_folder_1 folgendes gefunden:

    VB.NET-Quellcode

    1. Me.tb_folder_1 = New System.Windows.Forms.TextBox()


    Danach ist der Zugriff auf das Control dann auch:

    VB.NET-Quellcode

    1. Dim TBox As Windows.Forms.TextBox =tb_folder_1


    Das funktioniert soweit auch. Aber ich wollte ja auf das Control, dass innerhalb eines Splitterpanels liegt (zur Erinnerung), über den Namen zugreifen.

    Vor dem Einfügen des Splitters und der Verschiebung in den Splitter konnte ich wie folgt auf das Control zugreifen.

    VB.NET-Quellcode

    1. Dim TBox As Windows.Forms.TextBox = Me.Controls("tb_folder_" & Idx.ToString)


    Nun aber geht es wie gesagt nicht mehr.

    Verstehen muss ich das nicht !!!

    Gruß Jan

    jan99 schrieb:

    VB.NET-Quellcode

    1. Me.Controls("tb_folder_" & Idx.ToString)
    Wenn das Control Member des Split-Containers ist, sollte da statt Me.Controls so was stehen wie Me.SplitContainer1.Panel1("Name").
    Wie das genau heißt, entnimmst Du dem Designercode.
    Du musst das Control natürlich in dem Panel positionieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Moin!

    also in der Splitterstruktur muss es demnach schon einmal liegen.



    Auch über folgenden Code kann ich auf das Control zugreifen:

    VB.NET-Quellcode

    1. Dim TBox As Windows.Forms.TextBox = Me.SC_Horizontal.Panel1.Controls("tb_folder_" & Idx.ToString)


    Ich würde aber gerne in dem Namen Panelx das x durch

    VB.NET-Quellcode

    1. Idx.ToString


    ersetzen.

    Aber wie???

    Gruß Jan

    jan99 schrieb:

    ersetzen
    Indewm Du den richtigen Namens-Konstrukt da rein schreibst.
    Wie genau heißt / heißen denn Dein Control / Deine Controls?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    jan99 schrieb:

    Aber ich wollte ja auf das Control, dass innerhalb eines Splitterpanels liegt (zur Erinnerung), über den Namen zugreifen.
    Dassis Grütze. Und in deim Fall obendrein StrictOff.

    Im Gegensatz dazu: Was ist daran schlecht?

    VB.NET-Quellcode

    1. Dim TBox As Windows.Forms.TextBox =tb_folder_1


    Aber mach doch erstmal Strict On, bevor man sich da weiter reinhängt.
    Moin!

    wenn ich StrictOn setze, dann bekomme ich

    VB.NET-Quellcode

    1. Dim TBox As Windows.Forms.TextBox = CType(Me.SC_Horizontal.Panel1.Controls("tb_folder_" & Idx.ToString), TextBox)


    vorgeschlagen. Das ist ja soweit auch ok. Aber wie bekomme ich in dem Namen Panel1 die Nummer gegen eine Variable ausgetauscht.

    Hintergund ist, dass ich denselben Code einmal für 1 und einmal für 2 benötige.

    Gruß Jan
    Die beiden Splitterpanel des SplitContainer besitzen intern keine Namen
    Wenn man eine Referenz eines der SplitterPanel will, kann man das auch so machen.

    VB.NET-Quellcode

    1. Dim referecesplitterpanel As SplitterPanel = If(idx = 0, Me.SplitContainer1.Panel1, Me.SplitContainer1.Panel2)


    Aber wie schon von EDR gesagt. Es ist besser die Referenz einer Textbox vom Original abzuholen.

    VB.NET-Quellcode

    1. Dim referencetextbox = Me.tb_folder_1


    Freundliche Grüsse

    exc-jdbi
    @jan99 Kannst Du zunächst meine Frage von Post #9 beantworten?

    RodFromGermany schrieb:

    Wie genau heißt / heißen denn Dein Control / Deine Controls?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    jan99 schrieb:

    ...bekomme ich

    VB.NET-Quellcode

    1. Dim TBox As Windows.Forms.TextBox = CType(Me.SC_Horizontal.Panel1.Controls("tb_folder_" & Idx.ToString), TextBox)
    vorgeschlagen. Das ist ja soweit auch ok.
    Ist es nicht.
    Kannst du nicht erkennen, dass das von mir vorgeschlagene

    VB.NET-Quellcode

    1. Dim TBox As TextBox =tb_folder_1
    unglaublich unvergleichlich besser lesbar ist?
    Und Verschreiber oder eine fehlschlagende Typumwandlung kanns da garnet geben, weil die Typen passen eben zueinander.
    Daher meine Frage (auf die ich gern eine Antwort hätte): Was ist an meim Vorschlag so schlecht, dass du unbedingt diese unleserliche und anfällige Grütze vorziehen möchtest?
    Moin !
    es ist nichts schlecht an Deiner Formulierung.

    Definiere meine Zielsetzung einfach nochmal neu - vielleicht bin ich bei meiner Vorgehensweise irgendwie auf dem Holzweg.

    Es gibt eine Funktion für verschiedene Index-Werte. Jedem Index ist eine TextBox tb_folder_x zugewiesen.

    Wie spreche ich das Control richtig an? Als Randinfo - die TextBox liegt innerhalb eines Spitterpanels, falls es wichtig ist.

    VB.NET-Quellcode

    1. Private Sub bt_VerzeichnisWählen_Work(Index As VerzNum)
    2. Dim Idx As Integer = CInt(Index)
    3. Dim TBox As Windows.Forms.TextBox = Me.Controls("tb_folder_" & Idx.ToString)


    Gruß Jan

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jan99“ ()

    @jan99 Das kannst Du wesentlich bequemer lösen:

    VB.NET-Quellcode

    1. Dim tb() As TextBox = { TextBox1, TextBox2, TextBox3 }
    2. tb(idx).Text = "Bla"
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo Rod,

    bequemer ja, aber ist das so flexible wie ich mir das gedacht hatte?

    Aber was mich wundert, als ich den Splitte noch nicht verwendet hatte hat es funktioniert mit meinem

    VB.NET-Quellcode

    1. Dim TBox As Windows.Forms.TextBox = Me.Controls("tb_folder_" & Idx.ToString)


    !!!!!!

    Da ich nun diesen Zugriff auf die Controls an mehreren Stellen nutzen wollte hatte ich in der Classendefinition die Variablen definiert.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private _TB() As TextBox = {tb_folder_1, tb_folder_2}
    3. Private _PB() As PictureBox = {pb_folder_1, pb_folder_2}
    4. Private _LB_CFolder() As Label = {lbl_count_dir_1, lbl_count_dir_2}
    5. Private _LB_CFile() As Label = {lbl_count_file_1, lbl_count_file_2}
    6. Private _DGV() As DataGridView = {dgv_1, dgv_2}


    Der erste Aufruf einer der Controls erfolgt aus LOAD heraus und nun habe ich festgestellt das die Variablen noch nothing haben.

    Kann ich das irgendwie besser umgeben oder habe ich einen Denkfehler?

    Jan

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jan99“ ()

    Man könnte das auch irgendwie so lösen. So sind alle Controls zusammen. (Oder gleich Properties)
    Da braucht man einmal einen Index, und kann die vorhandene Sachen nutzen.

    Freundliche Grüsse

    exc-jdbi

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Public Class Form1
    4. Private RefControls() As RefControl
    5. Private Sub bt_VerzeichnisWählen_Work(ByVal Index As Int32)
    6. 'Mach was
    7. With Me.RefControls(Index)
    8. .BtnOfd.Enabled = False
    9. .Dgv.DataSource = MyDatasource
    10. Dim MyImage = New Bitmap(.Folder.Text)
    11. With .PBox
    12. .SizeMode = PictureBoxSizeMode.StretchImage
    13. .ClientSize = New Size(MyImage.Width, MyImage.Height)
    14. .Image = CType(MyImage, Image)
    15. End With
    16. .BtnOfd.Enabled = True
    17. End With
    18. End Sub
    19. Private Function GetRefControls() As RefControl()
    20. Dim ri1 = New RefControl() With {.BtnOfd = Me.BtnOfd1, _
    21. .CountDir = Me.CountDir1, _
    22. .CountFile = Me.CountFile1, _
    23. .Dgv = Me.Dgv1, _
    24. .PBox = Me.Icon1, _
    25. .Folder = Me.Folder1}
    26. Dim ri2 = New RefControl() With {.BtnOfd = Me.BtnOfd2, _
    27. .CountDir = Me.CountDir2, _
    28. .CountFile = Me.CountFile2, _
    29. .Dgv = Me.Dgv2, _
    30. .PBox = Me.Icon2, _
    31. .Folder = Me.Folder2}
    32. Return New RefControl() {ri1, ri2}
    33. End Function
    34. Public Sub New()
    35. MyBase.new()
    36. Me.InitializeComponent()
    37. Me.RefControls = Me.GetRefControls()
    38. End Sub
    39. End Class
    40. Public Class RefControl
    41. Public BtnOfd As Button
    42. Public Folder As TextBox
    43. Public CountDir As Label
    44. Public CountFile As Label
    45. Public PBox As PictureBox
    46. Public Dgv As DataGridView
    47. End Class

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „exc-jdbi“ ()

    Im Prinzip sollte das funktionieren, den sobald ein Konstruktor eröffnet wird, ist die Funktion

    VB.NET-Quellcode

    1. Me.InitializeComponent()

    drin. Hier werden alle Controls initialisiert+instanziert. Alles was nachher kommt, kann auf die entsprechenden Control's zugreifen und nutzen.

    Wen nalles schön sauber mit dem Designer gemacht worden ist, sollte keines der Controls Nothing haben.

    Ach so jetzt seh ich das Problem. So wie du es in #17 hast, kann das nicht funktionieren. Wie gesagt, die Funktion Me.InitializeComponent() muss zuerst durchlaufen werden. Oder eben in die LOAD-Events rein.

    VB.NET-Quellcode

    1. Public Class Form2
    2. Private _TB() As TextBox
    3. Private _LB_CFolder() As Label

    VB.NET-Quellcode

    1. Public Sub New()
    2. MyBase.new()
    3. Me.InitializeComponent()
    4. Me._TB = {Me.tb_folder_1, Me.tb_folder_2}
    5. Me._LB_CFolder = {Me.lbl_count_file_1, Me.lbl_count_file_2}
    6. End Sub



    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „exc-jdbi“ ()