Bei Koordinaten für eine Unterform die Position der Hauptform berücksichtigen

  • VB.NET
  • .NET (FX) 4.0

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von ~blaze~.

    Bei Koordinaten für eine Unterform die Position der Hauptform berücksichtigen

    Hallo,

    nachdem ich die Suche und das Google bemüht habe, versuche ich es mit diesem Thread.

    Problem:
    Bei zwei Monitoren kann es passieren, dass wenn die Anwendung vom Hauptbildschirm auf einen anderen verschoben wurde, andere (Unter-)Formen trotzdem auf dem ersten Bildschirm erscheinen. Das soll natürlich nicht passieren.
    Frage:
    Wie kann ich es verhindern?

    Danke und LG

    EDIT: hat sich erledigt, habe jetzt doch einen Thread dazu gefunden, wo man Location einstellt.
    Interessanterweise rechne ich schon sowieso Location aus, aber nur von untergeordneten Elementen der Hauptform, jetzt habe ich zusätzlich die Location der Hauptform für .Left benutzt.


    Eine bessere Beschreibung:

    Eine Unterform soll an einer bestimmten Stelle erscheinen, unter einem bestimmten Label im UserControl, welches in einem Panel auf der Hauptform angezeigt wird.
    Bisher hat es gut funktioniert, allerdings nicht auf mehreren Bildschirmen oder wenn die Hauptform verkleinert wird.
    Wie kann ich es berücksichtigen?

    VB.NET-Quellcode

    1. Dim left = 25 + Panel_Aussperr.Location.X + +winform.mainForm_.Panel_Content.Location.X + winform.mainForm_.Location.X


    So habe ich es versucht, allerdings funktioniert es nicht genau, z.B. ist die letzte Variable bei mir -8, obwohl das Fenster maximiert ist.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „WhitePage“ ()

    Moin @WhitePage
    Du musst den Formen im Designer .StartPosition = Manual geben und dann die .Location der Form selbst organisieren
    oder
    Du gibst den Formen .StartPosition = CenterParent.
    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!
    Ja, danke, das habe ich schon vorher gemacht.
    CenterParent geht eben nicht, weil die Unterform an einer bestimmten Stelle erscheinen soll (immer unterhalb eines bestimmten Labels).
    Habe oben schon editiert, habe jetzt die Berechnung erweitert.

    EDIT:
    @RodFromGermany
    Geht leider doch nicht, weil MainForm.Location.X bei einer verkleinerten Anwendung alles mögliche sein kann...
    Du könntest du Bounds-Property der ersten Form der nächsten übergeben:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim frm As New Form2
    3. frm.StartPosition = FormStartPosition.Manual
    4. frm.Bounds = Me.Bounds
    5. frm.Show()
    6. End Sub


    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    @WhitePage So was:

    VB.NET-Quellcode

    1. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    2. Using dlg = New Form2
    3. dlg.Location = Me.PointToScreen(Me.Label1.Location)
    4. dlg.ShowDialog()
    5. End Using
    6. End Sub
    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!
    Das funktioniert nicht, weil Location vom Label relativ zu seinem Parent ist, und das ist ein Panel. Deswegen muss ich alles zusammen rechnen.

    Im Endeffekt funktioniert es mit MainForm.Location.X, nur dass diese eben bei mir einen Offset von -8 hat. Und ich natürlich nicht weiß, welcher Offset bei einem anderen Kunden da ist.

    WhitePage schrieb:

    Das funktioniert
    so:

    VB.NET-Quellcode

    1. Using dlg = New Form2
    2. Dim loc As Point = Me.PointToScreen(Me.Panel1.Location)
    3. loc.Offset(Me.Label1.Location)
    4. dlg.Location = loc
    5. dlg.ShowDialog()
    6. End Using
    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!
    Ne ne, da sind bestimmt 4 Parents dazwischen... Ich habe jetzt Offset ermittelt, indem ich annehme, dass am Anfang immer maximiert gestartet wird, und ich die Differenz zwischen Screen.GetBounds(lbl).X und mainform.Location.X als Offset speichere.
    Bei der Berechnung der Koordinaten wird es abgezogen.

    Zur Zeit kämpfe ich mit der Y-Koordinate, wenn das Fenster so minimiert wird, dass das Label nicht im sichtbaren Bereich liegt. Irgendwie wird die Form dann zu weit oben angezeigt...

    EDIT:
    @RodFromGermany

    Ich habe jetzt einfach mit Dim loc As Point = Me.PointToScreen(label.Location) versucht, aber leider stimmt die X-Koordinate nicht überein (Y muss ich sowieso anpassen, da habe ich nicht darauf geachtet), die Differenz ist auch deutlich größer, als mein berechneter Offset weiter oben.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „WhitePage“ ()

    Dann lies MSDN.

    PointToClient rechnet BildschirmPixel aufs Control um. (PointToScreen genau annersrum).
    ZB liefert Shared Control.MousePosition Bildschirmkoordinaten.
    Die kannste jetzt in Label-Koordinaten umrechnen, damit du etwa Werte erhälst, kompatibel zu dem, was Label.MouseMove-EventArgs (client-bezogen) liefern.

    Also im Label1_MouseMove sollte folgendes immer True ergeben:

    VB.NET-Quellcode

    1. dim b = e.Location = Label1.PointToClient(Control.MousePosition)
    2. 'annersrum
    3. dim b2 = Label1.PointToScreen(e.Location)=Control.MousePosition

    Und ebenso funztes mit jedem Control, was du auf deim Form hast.

    Deine Rechnung, wo du immer auf Me bezogen ausrechnest ergibt eiglich keinen Sinn.
    Me.PointToScreen ergibt die BildschirmKoordinaten der Label-Position, und dann Me. PointToClient() ergibt wieder die Label-Koordinaten, die du eh hast - also lbl.Location - oder?
    Hi

    WhitePage schrieb:

    wenn die Hauptform verkleinert wird

    Ist das ein zeitliches "wenn"? Sprich: Möchtest du auch auf Änderungen der Labelposition reagieren?

    Ansonsten wäre PointToScreen wohl schon die richtige Lösung.

    VB.NET-Quellcode

    1. unterform.Location = Label1.PointToScreen(New Point(0, Label1.Height))

    sollte das eigentlich sein, oder?

    Viele Grüße
    ~blaze~
    Wie ich schon sagte

    WhitePage schrieb:

    Ich habe jetzt einfach mit Dim loc As Point = Me.PointToScreen(label.Location) versucht, aber leider stimmt die X-Koordinate nicht überein (Y muss ich sowieso anpassen, da habe ich nicht darauf geachtet), die Differenz ist auch deutlich größer, als mein berechneter Offset weiter oben.


    Die Werte stimmen nicht, es sind mind. 15-20 Pixel weiter nach links.

    Ich habe es ja schon gestern gelöst, dass ich einfach den Offset der anfänglich maximierten Form dazurechne. Und bei verkleinerten Form rechne ich noch einen zusätzlichen Offset zwischen dem Bildschirmrand und der Form.

    @ErfinderDesRades
    Wenn bei mir schon die obige einfache Funktion nicht funktioniert, lohnt es sich nicht für mich, mich weiter einzulesen. Zumal ich keine Mausposition habe, sondern nur die Labelposition (aber eben nur relativ zum Panel und ich brauche Bildschirmkoordinaten für Unterform.Location).
    Die Label-BildschirmKoordinaten kriegst du mit

    VB.NET-Quellcode

    1. Label1.PointToScreen(Point.Empty)
    Das ist die linke obere Ecke des Labels (point ( 0, 0 ) ) in Screen-Koordinaten.
    Egal, ob das Label auf einem Panel sitzt oder sonstwo

    Und eine Form.Location ist automatisch in ScreenKoordinaten, denn ein Form ist ja ein TopLevel-Control.