Mithilfe der Koordinaten einen Button auswählen

  • VB.NET
  • .NET (FX) 4.0

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von Hilfe0987.

    Mithilfe der Koordinaten einen Button auswählen

    Hi Leute, ich nochmal!

    Kann man einen Button auswählen, wenn man die Koordinaten hat? (nicht die Systemweiten, sondern die Koordinaten im Programm, die man auch bei .Location festlegt)

    Zum Beispiel so hier:

    VB.NET-Quellcode

    1. Public Sub ControlSelect(control As Control)
    2. control.Select(140, 230) 'x=140; y=230
    3. 'Daten abrufen
    4. Msgbox(control.Name)
    5. End Sub


    Ich habe Google schon bemüht, aber es lässt sich nichts dazu finden!
    :thumbup:
    @Hilfe0987 Du hast die .Controls-Collection des Parents. Die klickerst Du durch und testest, ob Dein Punkt zu seinem Rectangle gehört.
    Ggf. musst Du noch die Koordinaten in ein gemeinsames Koordinatensystem transformieren:

    VB.NET-Quellcode

    1. For Each btn As Button In Me.Controls.OfType(Of Button)()
    2. Dim rect = New Rectangle(btn.Location, btn.Size)
    3. If rect.Contains(Cursor.Position) Then
    4. MessageBox.Show(btn.Name)
    5. End If
    6. Next
    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!
    @Hilfe0987 Du wirfst irgend ein Problem-Snippet hier in das Forum und erwartest von uns, dass wir Dir Deinen 100%ig getesteten laufenden Code liefern.
    Deine Eigenleistung besteht ausschließlich in C&P.
    Warst Du übrigens zu feige, meine Fragen in diesem Thread zu beantworten?

    RodFromGermany schrieb:

    Ggf. musst Du noch die Koordinaten in ein gemeinsames Koordinatensystem transformieren
    Wir erwarten von Dir, dass Du unsere Posts liest und Eigeninitiative ergeifst.
    Ich erwaerte von Dir, dass Du zumindest die richtigen Funktionen dafür findest. X(
    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!
    @Hilfe0987 Dann formuliere doch mal eine vollständige Frage dazu, nicht aber so ein zusammenhangloser Satz

    Hilfe0987 schrieb:

    Ich hab es probiert aber nie kommt eine MessageBox
    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!
    Ich hab es probiert aber nie kommt eine MessageBox

    Das liegt daran, dass die Koordinaten des Cursors auf den Bildschirm bezogen sind. Du muss also Cursor.Position in relative koordinaten umrechnen. Zu deinem Glück stellt das .NetFramework bereits eine Fertige Funktion zur verfügung, diese heisst PointToClient(Point).

    Damit hast du nur immer noch das Problem mit der richtigen Auswertung. Wenn du nun die C&P -Bremse von RodFromGermany aus dem Snippet entfernnst bekommst du ledeglich den Button der gedrückt wurde.
    Dann müßtest du immer noch die umliegenden Buttons ermitteln. Der für dich bessere Lösungsweg wäre vermutlich mit Rectangle.IntersectWith zu arbeiten.
    Hier müßtest du ein Rectangle erstellen das dem Gedrückten Button dartstellt. Anschließend musst du alle Buttons durchlaufen, bei jedem Durchlauf prüfst du ob es sich um den gedrückten Button handelt, wenn nicht, erstellst du dir ein weiteres Rectangle das dem aktuellem Button entspricht. Nun kannst du mittels IntersectWith prüfen ob die Beiden Rectangles eine Schnittstelle bilden. Wenn dem so ist grenzt der Button an den geklickten Button an.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub OnButtonClick(sender As Object, e As EventArgs)
    2. ' Falls Buttons selektiert sind werden diese wieder auf standart gesetzt
    3. ' ClearSelectedButtons()
    4. ' Ermitteln welcher Button gedrückt wurde
    5. Dim btnSender As Button = DirectCast(sender, Button)
    6. ' Rectangle des Buttons erstellen, dieses Rectangle wird um 5 Gößeneinheiten größer als der Button selbst.
    7. ' Dadurch wird sichergestellt das die umliegenden Buttons auch ermittelt werden können
    8. Dim rectBtnSender As New Rectangle(btnSender.Location.X - 5, btnSender.Location.Y - 5, btnSender.Width + 10, btnSender.Height + 10)
    9. ' Alle Buttons durchlaufen und prüfen ob die Rectangles der Button eine Schnittmenge mit dem geklickten Button ergeben
    10. For Each btn As Button In Me.Controls.OfType(Of Button)()
    11. If btn IsNot btnSender Then
    12. Dim rectCurBtn As New Rectangle(btn.Location, btn.Size) ' Rectangle des aktuellen Buttons instanzieren
    13. If rectBtnSender.IntersectsWith(rectCurBtn) Then
    14. btn.BackColor = Color.Red
    15. ' lstSelectedButtons.Add(btn)
    16. End If
    17. End If
    18. Next
    19. End Sub

    Fakiz schrieb:

    For Each btn As Button In Me.Controls.OfType(Of Button)()


    Ich habe jetzt neuerdings zwei UCl´s, die unterschiedlich geladen werden, wenn eine bestimmte Bedingung erfüllt ist.
    Diese UCL wird dann in ein Panel eingefügt, während die Form lädt, und zwar so:

    VB.NET-Quellcode

    1. Dim ucl = New ucl_fall_1
    2. Panel1.Controls.Add(ucl)


    Und jetzt das Problem, dass die folgenden 2 Codeversuche nicht funktionieren:

    VB.NET-Quellcode

    1. For Each btn As Button In Panel1.Controls.OfType(Of Button)()
    2. ...


    VB.NET-Quellcode

    1. For Each btn As Button In ucl.Controls.OfType(Of Button)()
    2. ...


    Wie kann ich das jetzt realisieren? Die unteren zwei Codezeilen sollen ausgeführt werden, sobald ein Button im Panel1 gedrückt wird (das funktioniert schon, keine Sorge, nur funktioniert die for each btn Anweisung nicht)
    :thumbup:
    Naja dann werden die Buttons nach aussen nicht sichtbar sein. Du kannst dir mal die öffenltiche Controls deines UserControls ausgeben lassen.

    VB.NET-Quellcode

    1. For Each ctrl As Control In ucl.Controls
    2. Console.WriteLine("Name: {0}, Type: {1}", ctrl.Name, ctrl.GetType())
    @Fakiz
    Hab´s jetzt selber hinbekommen, und zwar:
    ich frage zuerst ab, ob es eine control auf dem Panel1 gibt, mit dem Name.contains("ucl").
    Den Name der UCL schreibe ich dann in ein String (ist kein String sondern dim ucl_name as control).
    Jetzt kann ich jedes Objekt in ucl_name.controls abrufen (sind nur noch die Felder) und anschließend prüfen, ob Sie neben dem geklickten Button liegen.

    Danke für eure Hilfe, vorallem @Fakiz!
    :thumbup:

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