Tipp für eine Vorgehensweise - Controlsteuerung in Form

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von jan99.

    Tipp für eine Vorgehensweise - Controlsteuerung in Form

    Moin!

    ich brauche einmal eine Idee von Euch.

    Es gibt ein Begriff, nennen wir diesen ATTRIBUT und dazu gibt es vielleicht eine Checkbox (CB_ATTRIBUT), eine Textbox (TXT_ATTRIBUT), eine PictureBox (PIC_ATTRIBUT) .... immer nach demselben Schema aufgebaut für "viele" Attribute

    Nun möchte ich, soweit vorhanden das CB, TXT oder PIC-Control ermitteln.

    Ich hatte schon einmal vor langer Zeit nach der Möglichkeit gefragt, man aus Namen (= "CB" & "_ATTRIBUT") ein Control ableiten kann. Das war nicht von Erfolg gekrönt, wenn ich mich recht entsinne.

    Aber wie geht man bei soetwas am besten vor???

    Hat einer von Euch eine Idee????

    Gruß Jan

    jan99 schrieb:

    dazu gibt es vielleicht
    Vielleicht aber auch nicht. Aber wurscht.

    VB.NET-Quellcode

    1. Dim MyControlsWithAttributAtTheEndOfTheName = Me.Controls.Cast(Of Control).Where(Function(x) x.Name.EndsWith("_ATTRIBUT"))
    Damit bekommst Du alle Controls, die "_ATTRIBUT" am Ende im Namen haben.

    jan99 schrieb:

    Aber wie geht man bei soetwas am besten vor???
    Indem man sich von der Idee verabschiedet, Controls nach Namen zu suchen, zumindest während der Laufzeit und die Controls in einem UserControl kombiniert, die zusammengehören.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Indem man sich von der Idee verabschiedet, Controls nach Namen zu suchen, zumindest während der Laufzeit und die Controls in einem UserControl kombiniert, die zusammengehören.


    Alternativ erstellt man einfach Controls, basierend auf den von Microsoft zur Verfügung gestellten und klappert die mit Pattern-Matching ab, sofern man kein eigenes UserControl dafür implementieren möchte.

    C#-Quellcode

    1. public class MyCheckBox: CheckBox { }
    2. void Foo() {
    3. foreach (var ctrl in Controls.Where(x => x is MyCheckBox)) {
    4. // irgendwie so in der Art
    5. }
    6. }
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.
    @jan99 Wie sehen denn mehrere dieser Gruppierungen aus? Lassen die sich in ein UIserControl einbauen?
    In Erweiterung zum Vorschlag von @Haudruferzappeltnoch kannst Du auch je ein Array für CheckBoxen, TextBoxen und PictureBoxen anlegen und dort mit dem entsprechenden Index arbeiten.
    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!

    danke erst einmal.

    User Controls habe ich bisher nicht erstellt und somit keine Erfahrungen damit wir erstellen und einsetzen.

    Bin jetzt am See und daher keinen Rechner zur Hand.

    Also folgende Kombinationen sind pauschal denkbar.

    Label+Textbox+Pictogramm für eine Kennzeichnung
    Label+Combobox

    Primär wollte ich das ganze auch haben um beides in einem Zuge zu diaenablen.

    Ich hoffe das Hilft weiter.

    Morgen kann ich erste Dialoge posten.

    Jan
    @jan99 Das ist doch eine glänzende Gelegenheit, Dich mit dem Konzept von UserControls zu befassen.
    Bei Deinen 1363 Beiträgen im Forum sollte Dir das doch ganz easy gelingen. :thumbup:
    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!

    jetzt fasse ich die aktuelle Aufgabenstellung einmal komplett zusammen.

    Ich habe Daten, die aus einer ID und einem Begriff bestehen und diese sind in einem Dictionary zusammengefasst. Nehmen wir einmal an die Begriffe sind Anlagenart. Von diesen Daten gibt es eine Vielzahl - z.B. Mitarbeiter, Kategorien etc.....

    Bisher habe ich immer in einem Dialog, wo die Daten ausgewählt werden sollen ein Label, eine Combobox und eine PictureBox (Hinweis, wenn bei Bedarf noch keine Auswahl vorliegt) eingefügt. Das ganze habe ich codiert und hat auch seinen Dienst getan.

    Nun habe ich einen Dialog wo diese Auswahlelemente bis zu 10x vorkommen und dass wurde mir langsam zu aufwendig und fehleranfällig. Deshalb kam ich auf den Gedanken mir ein UC zu erstellen um die wesentlichen Punkte zusammenzufassen.



    Mit der Auswahl eines Werte soll dann dieser von dem UC als Ergebnis abgefragt werden. Wenn keine Auswahl erfolgt ist, dann ist dieser Rückgabewert -1.

    Also wenn in einem der vorangegangenen Beiträge davon gesprochen wurde das man schnell eigene Eigenschaften haben will, dann muss ich an dieser Stelle enttäuschen. Vermutlich seid ihr schon einen Schritt weiter als ich.

    Um diese Auswahl abzufragen und auch in dem UC zu prüfen, ob eine Auswahl vorliegt (wenn erforderlich -> Required-Eigenschaft) wollte ich auf das Combo-Control zugreifen.

    Jetzt wo ich schreibe kommt mir gerade der Gedanke, dass vielleicht auch auf die Auswahl irgendwie im UC schon reagiert werden kann und so die Anzeige der Picturebox reagiert werden kann. Aber dennoch muss ich irgendwie an den aktuellen Werte der Combobox gelangen. Somit muss ich ja auch irgendwie an die SeletectedIndex-Eigenschaft der Combobox gelangen. Und das ist meine große derzeitige Aufgabenstellung.

    Nun einmal der Code den ich bisher erstellt habe:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Windows.Forms
    2. Public Class CTRL_Combo
    3. Private _Required_Input As Boolean = False
    4. Private _CurrentID As Long = -1
    5. Private _Data As New Dictionary(Of Long, String)
    6. Private _Msg4ToolTippRequired As String = "erforderliche Info wurde nicht gewählt!"
    7. ''' <summary>
    8. ''' Text für das Label
    9. ''' </summary>
    10. Public Property ComboLabel As String
    11. Get
    12. Return Label1.Text
    13. End Get
    14. Set(value As String)
    15. Label1.Text = value
    16. End Set
    17. End Property
    18. ''' <summary>
    19. ''' Erforderliche Eingabe
    20. ''' </summary>
    21. Public Property Required As Boolean
    22. Get
    23. Return _Required_Input
    24. End Get
    25. Set(value As Boolean)
    26. _Required_Input = value
    27. End Set
    28. End Property
    29. ''' <summary>
    30. ''' Daten für das Steuerelement
    31. ''' </summary>
    32. Public WriteOnly Property Data As Dictionary(Of Long, String)
    33. Set(value As Dictionary(Of Long, String))
    34. _Data = value
    35. FillCombo()
    36. End Set
    37. End Property
    38. ''' <summary>
    39. ''' Text für die Fehlermeldung, wenn erforderlich
    40. ''' </summary>
    41. Public WriteOnly Property Msg4ToolTippRequired As String
    42. Set(value As String)
    43. _Msg4ToolTippRequired = value
    44. End Set
    45. End Property
    46. ''' <summary>
    47. ''' Liegt ein Wert vor
    48. ''' </summary>
    49. Public ReadOnly Property HasValue As Boolean
    50. Get
    51. Return PictureBox1.Visible
    52. End Get
    53. End Property
    54. ''' <summary>
    55. ''' Aktuelle ID aus der TBD
    56. ''' </summary>
    57. ''' <returns>-1 ... keine Belegung</returns>
    58. Public Property ID As Integer
    59. Get
    60. Return _CurrentID
    61. End Get
    62. Set(value As Integer)
    63. _CurrentID = value
    64. End Set
    65. End Property
    66. ''' <summary>
    67. ''' zentrale Buttonüberwachung
    68. ''' </summary>
    69. Private Sub ZentralButtonControl()
    70. If _Required_Input = True Then
    71. If _CurrentID < 1 Then ' Überwachung der Combobox
    72. PictureBox1.Visible = True
    73. Dim t3b As New ToolTip
    74. t3b.SetToolTip(PictureBox1, _Msg4ToolTippRequired)
    75. Else
    76. PictureBox1.Visible = False
    77. End If
    78. Else
    79. PictureBox1.Visible = False
    80. End If
    81. End Sub
    82. ''' <summary>
    83. ''' befüllen der Klappliste
    84. ''' </summary>
    85. Public Sub FillCombo()
    86. If _Data.Count > 0 Then
    87. With ComboBox1 ' zuweisen der Daten
    88. Dim NewBindingSource As New BindingSource With {.DataSource = _Data}
    89. .DataSource = NewBindingSource
    90. .DisplayMember = "Value"
    91. .ValueMember = "Key"
    92. .SelectedIndex = -1
    93. .Enabled = True
    94. End With
    95. Else
    96. 'Todo: hier muss eventuell noch etwas ergänzt werden
    97. ComboBox1.Enabled = False
    98. End If
    99. End Sub
    100. ''' <summary>
    101. ''' Reaktion auf Werteänderung
    102. ''' </summary>
    103. Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs)
    104. _CurrentID = GetControlValueAsInt(ComboBox1)
    105. End Sub
    106. ''' <summary>
    107. ''' auslesen des aktuellen Wertes aus der Combobox - Integer
    108. ''' </summary>
    109. ''' <param name="Control">Combobox-Element</param>
    110. ''' <returns>Wert oder -1</returns>
    111. Public Function GetControlValueAsInt(Control As System.Windows.Forms.ComboBox) As Integer
    112. Dim Result As KeyValuePair(Of Long, String) = Nothing
    113. With Control
    114. If IsNothing(.SelectedValue) Then
    115. Return -1
    116. Else
    117. If TypeOf (.SelectedValue) Is Long Then
    118. Return CLng(.SelectedValue)
    119. Else
    120. Result = .SelectedValue
    121. Return CLng(Result.Key)
    122. End If
    123. End If
    124. End With
    125. Return -1
    126. End Function
    127. ''' <summary>
    128. ''' Initalisierung des UserControl
    129. ''' </summary>
    130. Private Sub CTRL_Combo_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    131. End Sub
    132. End Class


    Ich hatte gerade noch die Idee, weil ich ja im UC folgendes codiert hatte:

    VB.NET-Quellcode

    1. Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs)
    2. _CurrentID = GetControlValueAsInt(ComboBox1)
    3. End Sub


    und _CurrentID als ID in den Eigenschaften ausgegeben wird könnte ich so an den Wert gelangen. Aber leider kam da nicht das gewüschte Ergebnis.

    In meiner Unwissenheit hatte ich einen Haltepunkt im UC in diese Funktion gesetzt - aber da wurde nicht angehalten!

    Zwischenfrage: kann man im Code eines UC genauso debuggen und Haltepunkte setzen, wie in einer Klasse??

    Da ich nun nicht weiß, ob diese Angaben für Euch ausreichen abschließend noch etwas Code vom bisherigen Aufruf in de Dialog wo das UC eingebaut werden soll.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Windows
    3. Imports System.Windows.Ink
    4. Imports Mum.Geo.DataAccess
    5. Public Class DLG_AW_GSE_Bausache_Ablauf_Basic
    6. Private _MyApp As Mum.Geo.Client.Application
    7. Private _connection As Connection
    8. Private _fCntr As EBL.MapEdit.FUNC_Controls
    9. Private _EBLog As FUNC_Log
    10. Private _fDbc As FUNC_DB_Connection
    11. Private _fBsTools As Func_Bausachen_Ablaufplan
    12. Private _FID As Long = -1
    13. Public Sub New(MyApp As Mum.Geo.Client.Application, connection As Connection, Optional FID As Long = -1)
    14. ' Dieser Aufruf ist für den Designer erforderlich.
    15. InitializeComponent()
    16. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    17. _MyApp = MyApp
    18. _connection = connection
    19. _EBLog = New FUNC_Log(MyApp)
    20. _fDbc = New FUNC_DB_Connection(_connection, _EBLog)
    21. _fCntr = New EBL.MapEdit.FUNC_Controls(_connection, _EBLog)
    22. _fBsTools = New Func_Bausachen_Ablaufplan
    23. End Sub
    24. ''' <summary>
    25. ''' Daten für die Comboboxen zusammentragen
    26. ''' </summary>
    27. Private Sub DataCollect()
    28. With _fBsTools
    29. ' Anlagenart
    30. ' hier wird der SQL für eine Datenermittlung im Anschluss generiert
    31. Dim SQL_AnlagenArt As String = .BuildSql("EBL_BS_ANLAGENART_TBD", ShortValue:=True)
    32. ' hier wird das Dictionary erstellt, dass dann als Datengrundlage für die Combo in dem UC erstellt
    33. EBL_CBO_ID_BS_ANLAGENART.Data = _fCntr.GetData4Control(SQL_AnlagenArt, -1)
    34. ....
    35. End With
    36. End Sub
    37. Private Sub DLG_AW_GSE_Bausache_Ablauf_Basic_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    38. DataCollect() ' Datenzuweisen
    39. End Sub
    40. End Class



    Wenn jetzt noch weitere Informationen erforderlich sind bitte fragen und ich reiche nach.

    Was mir noch eingefallen ist - irgendwie muss mein Dialog, in welchem das UC eingebunden ist, ja auch noch mitbekommen, dass eine Auswahländerung erfolgt ist. ?!?!?

    Ich hoffe meine Fragestellung ist jetzt etwas verständlicher.

    Jan

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

    jan99 schrieb:

    Zwischenfrage: kann man im Code eines UC genauso debuggen und Haltepunkte setzen, wie in einer Klasse??
    Ja klar. Diese Sub hat vermutlich keinen Verweis und wird nie aufgerufen. Da fehlt sicherlich die Handles Klause

    Du solltest besser gleich das in einer Property vorhalten, das du brauchst; mit dem Index musst du ja erst wieder an die Combobox dran damit der was nutze ist.
    Damit hast du theoretisch das Was erledigt, was die Kommunikation angeht, aber noch nicht das Wann.

    Wenn der User das Item selektiert dann wird der Eventhandler aufgerufen in dem UC also Zeile 106.
    Das Form kriegt davon aber noch nichts mit. Wenn das Form wissen muss wann der Wert geändert wird, dann erstellst du ein eigenes Event im UC. Und das wird dann vom Form widerum abonniert.

    VB.NET-Quellcode

    1. Public Class UserControl1
    2. Public Event UCButtonClicked()
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. RaiseEvent UCButtonClicked()
    5. End Sub
    6. End Class

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

    Kurzer Stileinwurf: Am besten die klassische Event-Signatur verwenden/beibehalten.

    VB.NET-Quellcode

    1. Public Event UCButtonClicked As EventHandler
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. RaiseEvent UCButtonClicked(Me, EventArgs.Empty) 'damit weiß ein Zuhörer, dass das Event vom UC ausging
    4. End Sub
    Denn wenn mehrere UCs existieren und so das Form oder ein anderer Zuhörer dieses Event von mehreren UCs abonniert hat, kann so ermittelt werden, wer da gefeuert hat.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.