Sender Tag auswerten



  • Danke, hast mir sehr geholfen.
    Hatte in meinem ersten Beitrag eigentlich gemeint:
    [cs]Convert.ToInt32(((Label)sender).Tag)[cs]

    Aber eine Frage hätte ich noch:
    Geht das was du mir geschrieben hast auch in einer Anweisung?

    Danke



  • sry für Doppelpost

    aber es kommt in deiner zweiten Zeile die selbe Fehlermeldung.
    Habe vorher es nicht richtig getestet.



  • Schreibst Du strings in Tag?



  • Hallo Hobby_Programmierer,

    hast du die Tags über den PropertyEditor (Eigenschaften-Fenster) eingegeben? Dann sind es Strings (so wie µ schon gefragt hat), auch wenn du dort Zahlen eingibst.
    Du müßtest dann mittels TryParse die Zahl auslesen:

    Label label = (Label)sender; // noch besser mittels "as Label"!!!
    int tag;
    string sTag = label.Tag as string;
    if (sTag != null) // Abfrage, ob auch wirklich ein String dort drin steht
    {
      if (Int32.TryParse(sTag, out tag))
      {
        // nun steht in 'tag' die korrekte Zahl
      }
      else
      {
        // Fehler beim Parsen (d.h. keine korrekte Zahl, z.B. Leerstring)
      }
    }
    

    Ansonsten laß dir einfach mal im Debugger den Typ von 'label.Tag' anzeigen.



  • "Tag" ist laus MSDN von der "Control" Basisklasse. Wozu also nach Label casten wenn man direkt eine "generischere" Methode machen kann.

    public int GetIntegerFromControlTag(object sender, int fallback)
    {
        var control = sender as Control;
        if (control == null) return fallback;
    
        int converted;
        return int.TryParse(control.Tag, NumberStyles.Integer, new CultureInfo(1033), out converted) ? converted : fallback;
    }
    

    Das kann man dann auch schön Testen ^^

    [TestMethod]
    public void GetIntegerFromControlTag_ObjectIsNotAControl_ReturnsFallback()
    {
        var target = new DemoClass();
    
        var actual = target.GetIntegerFromControlTag("string", 7);
    
        Assert.IsTrue(7, actual);
    }
    
    [TestMethod]
    public void GetIntegerFromControlTag_ControlTagIsAString_ReturnsFallback()
    {
        var target = new DemoClass();
        var control = new Label {Tag = "string"};
    
        var actual = target.GetIntegerFromControlTag(control, 7);
    
        Assert.IsTrue(7, actual);
    }
    
    [TestMethod]
    public void GetIntegerFromControlTag_ControlTagIsAnInteger_ReturnsTagInteger()
    {
        var target = new DemoClass();
        var control = new Label {Tag = 1};
    
        var actual = target.GetIntegerFromControlTag(control, 7);
    
        Assert.IsTrue(1, actual);
    }
    

    (alles hier im Forum getippt, muss nicht funktionieren)



  • Ich persönlich finde es äußert fragwürdig in der Tag-Eigenschaft was zu speichern.



  • Vielen Dank an Th69, denn ich habe es jetzt ähnlich wie er gelöst.

    Label label = sender as Label;
    int Tag;
    string sTag = label.Tag as string;
    int32.TryParse(sTag, out Tag);
    

    Firefighter schrieb:

    Ich persönlich finde es äußert fragwürdig in der Tag-Eigenschaft was zu speichern.

    Warum? Wie würdest du es machen wenn du eine Ereignissmethode für verschiedene Steuerelemente hättest, die Ereignissmethode aber mit if änderbar sein muss?



  • Warum?

    - Weil ich der Meinung bin das diese umhercasterei recht gefährlich ist.
    - Weil man mal schnell was vergessen kann wenn sich an den Tags was ändert oder wenn neue Labels hinzukommen.

    Wie würde ich es machen:

    - Naja, du könntest es über Bindings machen.
    - Oder du könntest die Labels im Code erzeugen, über eine Schleife und im Code anonyme Eventhandler anlegen und mit den erzeugten Indizies arbeiten.

    Da wir aber nicht wissen was du vorhast, können meine Ideen genauso gut fürn Müll sein 🙂



  • Hobby_Programmierer schrieb:

    Vielen Dank an Th69, denn ich habe es jetzt ähnlich wie er gelöst.

    Label label = sender as Label;
    int Tag;
    string sTag = label.Tag as string;
    int32.TryParse(sTag, out Tag);
    

    Wenn du schon mit "as" arbeitest, prüfe auch auf null, sonst hat das ganze keinen Sinn.
    Wenn du es nicht machst, knallt es bei der ersten Verwendung direkt mit einer NullReferenceException weg.

    Nur die Verwendung von "as" macht es nicht auf Magische Weise sicher.

    Unabhängig davon finde ich die Verwendung des Tags auch sehr Fragwürdig.

    Erstell doch eine Methode pro Steuerelement, die rufen dann die Eigentliche Methode mit einem Parameter auf.
    Dadurch entkoppelst du auch die UI von der Logik etwas.



  • @David W
    bei as auf null zu prüfen ist sinnlos, da ich die Tags im Designer eingebe und im Programm nie ändere

    @David W und Firefighter
    Ich programmiere ein Tic Tac Toe. Da jedesmal etwas ähnliches passieren muss, aber doch nicht gleich (wie muss der Computer reagieren...) sind mir die Tags angenehm.

    PS: Ich zwinge niemanden auch Tags zu benuzten! 😉



  • Hobby_Programmierer schrieb:

    @David W
    bei as auf null zu prüfen ist sinnlos, da ich die Tags im Designer eingebe und im Programm nie ändere

    Dann brauchst du es auch nicht mit "as" casten sondern kannst hart casten wie du es zuvor hattest.
    Dann sparst du dir den Runtime Typecheck.



  • Hobby_Programmierer schrieb:

    @David W
    bei as auf null zu prüfen ist sinnlos, da ich die Tags im Designer eingebe und im Programm nie ändere

    @David W und Firefighter
    Ich programmiere ein Tic Tac Toe. Da jedesmal etwas ähnliches passieren muss, aber doch nicht gleich (wie muss der Computer reagieren...) sind mir die Tags angenehm.

    PS: Ich zwinge niemanden auch Tags zu benuzten! 😉

    Ok jedem das seine 🙂



  • Tja, wir als Profi-Progger würden sowas nie benutzen. ⚠



  • Es ist eher eine Frage des Stils und was man für Ansprüche an sich selber hat.
    Ein guter Stil ist es mMn nicht. Projekte die ich selber schreibe sollen meinen eigenen Ansprüchen genügen (was sie allerdings selten schaffen, da ich sehr selbstkritisch bin).



  • Firefighter schrieb:

    Ich persönlich finde es äußert fragwürdig in der Tag-Eigenschaft was zu speichern.

    Dem stimme ich zu.

    Warum verarbeitest Du nicht den Namen der 9 Labels.

    Ich sehe da keinen Sinn "Tag" zu verarbeiten.

    Label label = sender as Label;
    
    MessageBox.Show(label.Name);
    

    Die Abfrage welches Label geklickt wurde, machst Du über eine if-Anweisung oder einer switch-case-Anweisung...

    Label label = sender as Label;
    
    switch (label.Name)
           {
               case "label1":
                  MessageBox.Show("1");
                  break;
    
               case "label2":
                  MessageBox.Show("2");
                  break;
    
               default:
                  MessageBox.Show("3");
                  break;  
            }
    


  • var allLabels = { label1, label2, label3, ..., ... };
    
    for(int i = 0; i < allLabels.Count; ++i)
    {
        int labelIndex = i;
        allLabels[i].OnClick = (eventArgs) => ProcessLabelClick(labelIndex);
    }
    


  • Sorry kleinere Fehler im vorherigen Beispiel. So könnte man mit einer Funktion alle Labels verarbeiten anhand des Index.

    void ProcessLabelClick(int i)
    {
        MessageBox.Show(i.ToString());
    }
    
    var allLabels = new List<Label> { label1, label2 };
    
    for (int i = 0; i < allLabels.Count; ++i)
    {
        int labelIndex = i;
        allLabels[i].Click += (sender, eventArgs) => ProcessLabelClick(labelIndex);
    }
    


  • Mit einer normalen Klick Methode ginge es nach diesen Prinzip auch, da man den Sender dann mit IndexOf in der Liste suchen kann und dann den Index bekommt.



  • @guten tag und David W

    Was ist denn so schlimm?
    Und was ist der Unterschied ob ich Tag oder Name benutze?
    Und vorallem: bei Name kann ich nicht nur eine Zahl eingeben, ich will es aber direkt im Index eines Arrays weiterverwenden.



  • Was ich daran schlimm finde? Die enge Kopplung zwischen Programmlogik und Oberfläche.
    Den Namen zu verwenden finde ich genauso falsch.


Anmelden zum Antworten