Abfrage "is Label" scheitert

  • VB.NET

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

    Abfrage "is Label" scheitert

    HI,

    ich habe ein recht simpless Syntax Problem. Kurz zum Background:

    Ich habe drei Label, denen ich ich mit Mouseclick Texte zuweisen will (z.B "=", "<", ">", "<")

    die Routine möchte ich natürlich nur einmal kodieren und nicht dreimal ... deshalb versuche ich folgendes Coding:

    VB.NET-Quellcode

    1. Dim charOptions As String() = {"starts", "contains", "not cont", "equal", "unequal", "off"}
    2. Dim numOptions As String() = {"<", "=", "<>", ">", "off"}
    3. Private Sub Label_Click(sender As Object, e As MouseEventArgs) Handles LblRecipient.MouseClick,
    4. LblAmount.MouseClick,
    5. LblCategory.MouseClick
    6. LblMessage.Text = ""
    7. Dim myLabel = DirectCast(sender, Label)
    8. Dim Options As String() = charOptions
    9. If myLabel Is LblAmount Then Options = numOptions
    10. 'If myLabel = LblAmount Then Options = numOptions
    11. Dim myOption As String = myLabel.text
    12. Dim i = Options.Length - 1
    13. If e.Button = MouseButtons.Left Then
    14. i = Array.IndexOf(Options, myOption) + 1
    15. If i > Options.Length - 1 Then i = 0
    16. End If
    17. myLabel.Text = Options(i)
    18. End Sub


    Das mache ich mit Buttons recht häufig und da funktioniert das auch.

    Mit Label klappt das aber leider nicht mehr.

    Die Abfrage

    VB.NET-Quellcode

    1. If myLabel Is LblAmount Then


    scheitert mit der Compiler Meldung:

    Der Is Operator akzeptiert keine Operanden vom Typ Label ...

    Wenn ich die Abfrage ändere

    VB.NET-Quellcode

    1. If myLabel = LblAmount Then


    dann erhalte ich die Fehlermedlung

    Der Wert vom Typ "Label" kann nicht in "Label" konvertiert werden.

    Diese Meldung verwirrt mich ganz offengestanden ! :)

    Wie kann ich denn das Label abfragen ... zur Not müsste ich halt die Routine "dreifach" kodieren ...

    Ich hoffe ich habe mein Problem verständlich machen können.

    LG
    Peter

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

    Ich hab's mal gerade nachgebaut und bei mir funktioniert das.



    C#-Quellcode

    1. public Form1() {
    2. InitializeComponent();
    3. label1.MouseClick += label_Click;
    4. label2.MouseClick += label_Click;
    5. label3.MouseClick += label_Click;
    6. }
    7. private void Form1_Load(object sender, EventArgs e) {
    8. }
    9. private void label_Click(object sender, EventArgs e) {
    10. if (sender is not Label myLabel) {
    11. Debug.WriteLine("Label is null?!");
    12. } else if (myLabel == label1) {
    13. Debug.WriteLine("Label is label1");
    14. } else if (myLabel == label2) {
    15. Debug.WriteLine("Label is label2");
    16. } else if (myLabel == label3) {
    17. Debug.WriteLine("Label is label3");
    18. } else {
    19. Debug.WriteLine("Label is something else");
    20. }
    21. }
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.
    Danke für den Nachbau ! Jau ... ich glaube das hat bei mir auch einmal funktioniert ... aber jetzt bringt das Dingens diese Fehlermeldung .... (s. Anhang)

    Und wie ich gerade festelle scheitert auch der direct cast ...

    System.InvalidCastException: "Die angegebene Umwandlung ist ungültig."

    Also irgendwas ist mit meiner Form nicht in Ordnung ...

    Im Designer sehen die Label (m.E) völlig normal aus ..

    Hat jemand eine Idee was da falsch sein könnte ?
    Bilder
    • s 2025-04-10 10-06-155.jpg

      157,89 kB, 1.220×711, 73 mal angesehen
    • s 2025-04-10 10-56-382.jpg

      91,32 kB, 1.224×361, 63 mal angesehen
    • s 2025-04-10 11-00-430.jpg

      160,26 kB, 1.451×794, 73 mal angesehen
    Ich wollte gerade große Töne spucken und sagen, dass du Patternmatching falsch anwendest; aber diese desolate Sprache unterstützt nicht mal Patternmatching :thumbdown:

    Probier's mal mit TryCast und prüfe dann auf Nothing.

    VB.NET-Quellcode

    1. dim myLabel = TryCast(sender, Label)
    2. if myLabel is nothing then return ' Funktion einfach abbrechen





    So, ich habe mir die Syntax von VB jetzt auch nochmal genauer angeschaut. Deine Abfrage mit Is sollte eigentlich genau wie in meinem C# Code funktionieren, da Is nicht den Wert prüft, sondern ob die Variablen auf den selben Speicher (die selbe Referenz) zeigen.
    Der Grund, warum deine Abfrage mit = nicht funktioniert, ist weil du damit die Werte vergleichst; zwei Referenzen zeigen natürlich auf den selben Speicher, haben allerdings unterschiedliche Werte.

    Hast du bei dir im Projekt Option Strict On aktiv? Oder könntest du das Projekt vielleicht mal testhalber hochladen, sodass wir deinen Ist-Zustand haben?
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.

    siycah schrieb:

    zwei Referenzen zeigen natürlich auf den selben Speicher, haben allerdings unterschiedliche Werte.
    Das versteh ich nicht, wenn a Is b, dann kann in a nich 2 drin stehen und in b 3.
    In c# und vb.net sind die Is Operatoren auch nicht übereinstimend. c# Is ist in vb.net TypeOf x Is

    Ich kann diese Fehler nachstellen, wenn ich eine eigene Label Klasse bastel, die eine Property Text hat.
    Aber da sagt mein Studio mir trotzdem ganz deutlich was wirklich vor sich geht: "Unable to cast object of type 'System.Windows.Forms.Label' to type 'Test.Label'"

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

    @Peter329 Dein Code, Deine Labels vor (separater Screenshot) und nach Klick:

    Mir ist völlig unklar, was bei Dir da abgeht.
    Und:
    Welchen Zweck hat Deine Variable Options?
    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!
    Hi,

    so .... jetzt hab ich die Ursache für das Problem gefunden:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Reflection.Emit


    Das VS hat sich einfach die Freiheit genommen, meinem Code einen zweiten (nicht benötigten) Import hinzuzufügen! Wann das passiert ist kann ich nicht sagen ... nur ich selbst habe diesen Import definitiv NICHT hinzugefügt!

    Nach dem Entfernen des Imports läuft die Sache wieder ohne Probleme.

    Hier möchte ich eins hinzufügen: ich stelle seit einiger Zeit immer wieder fest, dass das VS aus freien Stücken irgendwelche unnötigen Imports hinzufügt. Die erkennt man dann an der dunklen Färbung ... dann nehme ich die halt wieder raus. Normalerweise passiert da auch nix.

    In diesem Fall ist es ganz offensichtlich so, dass mein Programm fehlerfrei lief, bis der Import stillschweigend, aus heiterem Himmel vom VS hinzugefügt wurde und dadurch ein Konflikt mit dem Object "Label" verusacht wurde. Wie schon gesagt, ich habe keine Ahnung wodurch das veranlasst wurde .... ich jedenfalls hab den Quatsch nicht eingestellt!

    Ich habe das hier so auführlich diskutiert, weil sich ja auch andere (ähnlich unbedarfte) Nutzer an so einem Blödsinn die Zähne ausbeißen könnten. :)

    Na, vielleicht hilft das ja dem einen oder anderen.

    Vielen Dank für eure Mühe und Ratschläge. Daumen hoch und Problem gelöst!

    LG
    Peter

    Haudruferzappeltnoch schrieb:

    Das versteh ich nicht


    Sowohl VB als auch C# abstrahieren da ziemlich viel weg.
    Bei VB hat man (nebst vielen weiteren) den Fehler gemacht, unterschiedliche Operatoren für syntakisch gleiche Dinge zu nehmen.

    In diesem konkreten Fall gibt's = und is;

    is prüft, ob zwei Variablen den gleichen Speicher referenzieren.

    = prüft, ob die Werte gleich sind; deshalb nimmt der = Operator auch nur Skalare Werte, wie Zahlen, Arrays, etc. Damit verhindert Microsoft, dass die Pointer verglichen werden.

    In C/++ kann man das relativ deutlich darstellen: (unsicherer Code, NICHT irgendwo produktiv verwenden. Es dient lediglich der Anschauung).

    C-Quellcode

    1. #include <iostream>
    2. #include <cstring>
    3. static char* g_myObject = nullptr;
    4. int main() {
    5. g_myObject = new char[4096];
    6. memset(g_myObject, 0, 4096);
    7. printf("Address of g_myObject: %x\tpoints to memory => %x\n", &g_myObject, g_myObject);
    8. char* obj1 = g_myObject;
    9. printf("Address of obj1: %x\tpoints to => %x\n", &obj1, obj1);
    10. char* obj2 = g_myObject;
    11. printf("Address of obj2: %x\tpoints to => %x\n", &obj2, obj2);
    12. delete g_myObject;
    13. }


    Das gibt dann folgendes aus:

    Quellcode

    1. Address of g_myObject: 4e78d018 points to memory => 568d32b0
    2. Address of obj1: c849c738 points to => 568d32b0
    3. Address of obj2: c849c740 points to => 568d32b0


    Wenn du den Code nachbauen möchtest, kannst du ihn mit folgendem Befehl kompilieren: g++ cpptest.cpp -ocpptest
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.

    Peter329 schrieb:

    ich stelle seit einiger Zeit immer wieder fest, dass das VS aus freien Stücken irgendwelche unnötigen Imports hinzufügt
    Das passiert häufig, wenn man Code aus anderen Bereichen in eine Datei kopiert. Dann versucht VS das Beste aus unbekannten Komponenten zu machen und passende verfügbare/vermeitlich naheliegende Imports zu machen, damit der eingefügte Code vermeintlich fehlerfreier wird. Manchmal ist es gut geraten, manchmal geht die Sache nach hinen los, wie bei Dir.

    Kannst ja mal versuchen, das hier abzuschalten: Menü Extras -> Optionen -> Text-Editor -> Visual Basic -> Erweitert: [ ] Beim Einfügen fehlende Import-Anweisungen hinzufügen
    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.
    off topic Start:

    @VaporiZed

    jau ... das bestätigt meine Diagnose.

    Ich habe den Eindruck, dass VS gelegentlich zu viele (wenn auch gutgemeinte) Annahmen trifft. Klar, wenn man aus anderen Projekten oder Forms etwas hineinkopiert, dann kriegt man erst einmal eine Menge (erwarteter) Fehlermeldungen. Und dass VB dann durch Hinzufügen von Imports diese Fehler zu beheben versucht ist ja, ganz in Ordnung. Tatsächlich funktioniert das ja auch, wenn man auf Files zugreift und etwa ein Imports.IO fehlt.

    Wie wäre es, wenn VB sich "merkt" welche Imports dynamisch hinzugefügt wurden, und diese Einträge dann wieder entfernt wenn sie aufgrund nachfolgender Änderungen nicht mehr benötigt werden.

    Das sollte machbar sein und verhindern,. dass irgendwelche "Waisen-Imports" hängen bleiben.

    Nice to have ... vielleicht kommmt diese Idee ja bei Microsoft an.

    Ansonsten bleibt halt nur der Rat, dass man bei "unerklärlichen" Fehlern mal die Imports-Einträge kontrolliert. Wenn man (wie ich) einen Tag damit zugebracht hat ein "Phantom" zu jagen, dann schleift sich das ja ein ... :)

    Generell ist anzumerken, dass auch Intellisense dazu neigt, mehr zu korrigieren als nötig. Manche (zum Teil "hartnäckigen") Intellisense-Korrekturen sind eher hinderlich als nützlich.

    Aber so ist die Welt ... und wenn man nicht wie Don Quijote in den Windmühlenflügeln des .Net-Frameworks enden will, dann sollte man sich damit wohl besser abfinden. :)

    off topic Ende:

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

    Jau ... das ist VS2022 ...

    Und das mit den Kinderkrankheiten kann ich bestätigen ! Da gibt es noch einige andere zweifelhafte "Features" ... aber nix womit ich nicht klarkommen würde. Einige Dialoge haben sich massiv verändert ... die muss man dann erst mal verstehen ...