Code wird nicht richtig im Hintergrund ausgeführt

  • VB.NET
  • .NET 4.5

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

    Code wird nicht richtig im Hintergrund ausgeführt

    Hi,
    habe ein Problem mit meinem Code.
    Der Code berechnet die Position für ein Label, das immer wieder einen neuen Text bekommt und immer in der Mitte vom Panel1 sein soll (My.Settings.int1 = Panel1.Size.Width - ist in einem anderen Thread).
    Der Code zur Berechnung funktioniert, doch wenn ich bevor der Text sich ändert, in ein anderes Programm gehe, danach aber wieder mein Programm öffne und der Text sich währenddessen schon verändert haben sollte,
    wird er mir nirgends angezeigt. Abfragen durch Tests ergaben, dass alles eigentlich stimmen sollte, nur ich fand das Label nirgends. Dann habe ich zum Testen ganz oben die Programmzeile hinzugefügt:

    VB.NET-Quellcode

    1. ​MsgBox(SongTitleLabel.Size.Width)


    Jetzt funktionierte alles, also der Text wurde, nachdem ich auf OK (von der MsgBox) gedrückt habe, angezeigt, und zwar richtig in der Mitte positioniert, wie gewünscht.
    Anscheinend wurde der Code sonst irgendwie nicht gefocused oder irgendwie so? Wie kann ich den Code mit der Msgbox ersetzen, sodass die gleiche Wirkung erzielt wird,
    also dass der restliche Code funktioniert? Wie gesagt, ohne den MsgBox-Code war das Label einfach nirgends zu sehen.

    Der komplette Code:

    VB.NET-Quellcode

    1. MsgBox(SongTitleLabel.Size.Width)
    2. Dim int1 As Integer = My.Settings.int1
    3. Dim int2 As Integer = SongTitleLabel.Size.Width
    4. Dim int3 As Integer = 0
    5. int1 /= 2
    6. int2 /= 2
    7. int3 = int1
    8. int3 -= int2
    9. SongTitleLabel.Location = New Point(int3, SongTitleLabel.Location.Y)
    Probier doch mal ein einfaches Me.Update(), Me.Refresh() oder Me.Invalidate(), nachdem das Label in Zeile 9 verändert wurde.
    btw: MsgBox = Microsoft.VisualBasic (= VB6)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    VaporiZed schrieb:

    Probier doch mal ein einfaches Me.Update(), Me.Refresh() oder Me.Invalidate(), nachdem das Label in Zeile 9 verändert wurde.
    btw: MsgBox = Microsoft.VisualBasic (= VB6)
    Hab alle 3 probiert, Fehler bleibt.
    Hm … könnte an der Geschichte mit dem anderen Thread liegen (GUI darf nur durch den Mainthread verändert werden). Aber lass Dir mal späßleshalber nach der Veränderung der Labelposition dieselbige ausspucken. Kann sein, dass da ein interessantes Ergebnis rauskommt. Schiebst Du nur ein anderes Fenster drüber oder minimierst Du auch Dein Programm?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Nein ich minimiere das Programm wirklich bzw. öffne ein anderes.
    Die Location bleibt, soweit ich das in Erinnerung hab, habe nämlich mir beim testen alles ausgeben lassen. Und hab auch mal statt My.Settings ne Dim verwendet, der die Größe vom Panel abruft, der gibt dann 0 an als Größe, da das Programm ja minimiert ist. Komischerweise wird aber das Label danach angezeigt im Gegensatz zu dem Code ganz oben hier im Thread.
    Aber dafür sehr weit links und nicht richtig, aber dennoch wird es angezeigt (ist aber hinter einer picturesque die ganz rechts oben ist).
    Ja gut, eh … wenn man in die Gleichungen oben für Int1 bzw. Int3 Null einsetzt, hat man eine negative X-Koordinate für das Label innerhalb des Panels. Dann müsste die Hälfte des Labels quasi abgeschnitten sein und man sieht am linken Panelrand die rechte Labelhälfte.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Developement schrieb:

    My.Settings.int1 = Panel1.Size.Width

    Developement schrieb:

    der die Größe vom Panel abruft, der gibt dann 0 an als Größe, da das Programm ja minimiert ist

    => Wenn minimiert, dann ist Panel1.Width = 0 und somit My.Settings.int1 = 0

    VB.NET-Quellcode

    1. Dim int1 As Integer = My.Settings.int1 '= 0
    2. Dim int2 As Integer = SongTitleLabel.Size.Width ' = z.B. 50
    3. Dim int3 As Integer = 0
    4. int1 /= 2 '0 : 2 = 0
    5. int2 /= 2 '50 : 2 = 25
    6. int3 = int1 '= 0
    7. int3 -= int2 'int3 = 0 - 25 = -25
    8. SongTitleLabel.Location = New Point(int3, SongTitleLabel.Location.Y)[/quote] 'setze Label auf x = -25, y = ? => linker Rand!
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    VaporiZed schrieb:

    Developement schrieb:

    My.Settings.int1 = Panel1.Size.Width

    Developement schrieb:

    der die Größe vom Panel abruft, der gibt dann 0 an als Größe, da das Programm ja minimiert ist

    => Wenn minimiert, dann ist Panel1.Width = 0 und somit My.Settings.int1 = 0

    VB.NET-Quellcode

    1. Dim int1 As Integer = My.Settings.int1 '= 0
    2. Dim int2 As Integer = SongTitleLabel.Size.Width ' = z.B. 50
    3. Dim int3 As Integer = 0
    4. int1 /= 2 '0 : 2 = 0
    5. int2 /= 2 '50 : 2 = 25
    6. int3 = int1 '= 0
    7. int3 -= int2 'int3 = 0 - 25 = -25
    8. SongTitleLabel.Location = New Point(int3, SongTitleLabel.Location.Y)[/quote] 'setze Label auf x = -25, y = ? => linker Rand!


    nein. Ich setze die My.settings dafür nur 1x und zwar dann, wenn es nicht minimiert ist.
    Hab das mal nachgebaut:

    VB.NET-Quellcode

    1. Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. My.Settings.int1 = Panel1.Width
    3. CenterLabelAfterFiveSeconds()
    4. End Sub
    5. Private Async Sub CenterLabelAfterFiveSeconds()
    6. Await Threading.Tasks.Task.Delay(5000)
    7. Dim int1 As Integer = My.Settings.int1
    8. Dim int2 As Integer = SongTitleLabel.Size.Width
    9. Dim int3 As Integer = 0
    10. int1 \= 2 '/ wurden zu \, damit es zu Option Strict On passt
    11. int2 \= 2
    12. int3 = int1
    13. int3 -= int2
    14. SongTitleLabel.Location = New Point(int3, SongTitleLabel.Location.Y)
    15. End Sub

    Läuft. Nach 5 Sekunden wird das Label zentriert. Und zwar egal, ob das Form normal oder minimiert ist. Jetzt liegt es an Dir, die funktionalen Unterschiede zu Deinem Code zu finden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    @VaporiZed nein, nicht mal das funktioniert bei mir. Vielleicht liegts ja am restlichen Code? Ich schau mich mal ein bisschen selber um, ob da was falsch sein könnte^^

    EDIT:
    Hab's auch mal nochmal in nem neuen Test-Projekt nachgestellt.
    Folgender Code:

    VB.NET-Quellcode

    1. ​Public Class Form1
    2. Dim screenWidth As Integer = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width
    3. Private Sub GetSongTitleLabelLocation()
    4. 'MsgBox(SongTitleLabel.Size.Width)
    5. ' Dim int1 As Integer = Panel1.Size.Width
    6. 'TESTING AREA:
    7. 'MsgBox(My.Settings.int1 & screenWidth)
    8. SongTitleLabel.Text = "Text 2"
    9. Dim int1 As Integer = screenWidth
    10. Dim int2 As Integer = SongTitleLabel.Size.Width
    11. Dim int3 As Integer = 0
    12. int1 /= 2
    13. int2 /= 2
    14. int3 = int1
    15. int3 -= int2
    16. SongTitleLabel.Location = New Point(int3, SongTitleLabel.Location.Y)
    17. End Sub
    18. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    19. System.Threading.Thread.Sleep(3000)
    20. GetSongTitleLabelLocation()
    21. End Sub
    22. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    23. WindowState = System.Windows.Forms.FormWindowState.Maximized
    24. End Sub
    25. End Class

    Ich klicke auf den Button, minimiere das Programm (das reagiert zwar nicht, aber ich drück dann einfach auf das Icon in der Taskleiste um es zu minimieren) und der Text und die Location ändern sich nicht.
    Bei meinem Problem, wie ganz oben beschrieben, ist jedoch gar kein Label zu sehen?

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

    An alle: Gäbe es denn vlt. eine andere Lösung, das Label immer mittig zu halten? Also X-Koordinate immer mittig, Y kann bleiben.
    Andere Lösungen dazu bringen nichts, da dabei nicht die Länge des Strings berücksichtigt wird. Mein Code aus dem Post ganz oben klappt ja,
    aber gib ja wie gesagt die Problematik. Irgendwelche Ideen? ^^
    Hi
    sollte eigentlich x /= 2 nicht zu x \= 2 umgeschrieben werden müssen, um Option Strict-konform zu sein? Falls du es nicht aktiv hast, setze Option Strict auf On. Andernfalls wird es wahrscheinlich zu keinem schönen Code kommen.

    meine Empfehlung ist, das Layout über TableLayoutPanel, FlowLayoutPanel, usw. und Dock oder Anchor zu lösen. Außerdem sind auch MinimumSize, Margin, Padding und AutoSize in Kombination mit AutoSizeMode deine Freunde. Einige Steuerelemente bieten diese an. Damit wirst du quasi alle Layout-Probleme los.

    Viele Grüße
    ~blaze~

    ~blaze~ schrieb:

    sollte eigentlich x /= 2 nicht zu x \= 2 umgeschrieben werden müssen, um Option Strict-konform zu sein? Falls du es nicht aktiv hast, setze Option Strict auf On. Andernfalls wird es wahrscheinlich zu keinem schönen Code kommen.
    Geändert.

    ~blaze~ schrieb:

    meine Empfehlung ist, das Layout über TableLayoutPanel, FlowLayoutPanel, usw. und Dock oder Anchor zu lösen. Außerdem sind auch MinimumSize, Margin, Padding und AutoSize in Kombination mit AutoSizeMode deine Freunde. Einige Steuerelemente bieten diese an. Damit wirst du quasi alle Layout-Probleme los.


    Wird dadurch dann auch bei änderndem Text automatisch in die Mitte zentriert und darauf geachtet, dass der Label-Text auch ne Länge hat?
    Und mit welchen von denen löst man das dann am einfachsten, besten?

    EDIT:
    Hab's jetzt mit AutoSize=False, TextAlign=MiddleCenter und Anchor=Left, Right geschafft bei nem Testprojekt.
    Melde mich, wenn es beim originalen Projekt auch klappen sollte.

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

    Endlich. Habe es nun geschafft.
    Habe den Code gelöscht, dafür wie @~blaze~ gesagt hat, alles mit den Layout-Optionen gemacht.
    Hat geklappt, irgendwie wollte der Code nicht wirklich im Hintergrund die Position anpassen.
    Und ist im Endeffekt die definitiv elegantere Methode, da es jetzt ohne irgendwelches Flimmern positioniert wird,
    davor hat es ein wenig gespackt.
    Einstellungen:

    Quellcode

    1. ​Dock= Fill
    2. AutoSize=False
    3. TextAlign=MiddleCenter
    4. Anchor=Left, Right
    Mit AutoSize = True in einem TableLayoutPanel mit Anchor = None und auf dem TableLayoutPanel mit der Column, in der sich das Label befindet auf AutoSize (dazu das Menü zum Spalten und Reihen editieren öffnen).
    Die restlichen Spalten und Reihen werden dann eben mit den Steuerelementen befüllt, die das Label umgeben sollen. Beachte, dass das TableLayoutPanel weitere Eigenschaften (ich glaube RowSpan und ColumnSpan) zu den enthaltenen Steuerelementen hinzufügt, die angeben, wie viele Reihen und Spalten das enthaltene Steuerelement ausfüllen soll.
    Rand kannst du über die Padding-Eigenschaft angeben, wenn ich mich richtig erinnere. Offenbar mache ich zu wenig mit GUI.

    Edit: Btw. fällt Anchor = None nur dann ins Gewicht, wenn es weitere Steuerelemente in der Spalte gibt, die die Spalte größer werden lassen. Würde ich dennoch aktivieren, damit zukünftige Änderungen reibungslos klappen. Sofern es veritkal nicht zentriert werden soll, musst du halt entsprechend Top oder Bottom aktivieren, um es oben oder unten auszurichten.

    Viele Grüße
    ~blaze~

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

    AndPod schrieb:

    Also wie ich bereits im Post 9 geschrieben habe?

    Ja, eben durch Anchors, Docks usw. lösen, wollte die Lösung vorerst aber nicht ausprobieren, wegen:

    AndPod schrieb:

    Könnte ja dann maximal optisch irgendwie nicht so toll aussehen

    Sieht aber perfekt aus. Gibt keine Bugs etc.
    Das Problem zeigt sich dann erst, sobald der Text im Label nicht mehr in die vorgesehene Größe passt. Bei hoher DPI-Zahl ist das durchaus möglich. Also: Über AutoSize = True und die vorgesehenen Einstellungen arbeiten. Du musst dir die Art des Layouts sowieso irgendwann mal zu Gemüte führen, das kann insofern auch gleich jetzt sein.

    Viele Grüße
    ~blaze~