C# INotifyPropertyChanged, auf geänderte Eigenschaft zugreifen

Gast #2389672
Lesenswert?

Hallo,

ich habe eine Klasse geschrieben, die die INotifyPropertyChanged 
Schnittstelle implementiert und die eine PropertyChangedEvent auslöst, 
wenn sich eine ihrer Eigenschaften ändert.
Wie kann ich nun im EventHandler auf die geänderte Eigenschaft 
zugreifen?
Der EventHandler sieht so aus:
1
private void On_PropertyChanged(object sender, PropertyChangedEventArgs e)
2
{
3
                      
4
}

e hat eine Eigenschaft vom Typ String namens e.PropertyName, in der der 
Name der geänderten Klasseneigenschaft steht. Nun weiß ich nicht, wie 
ich mit Hilfe des Strings auf diese Klasseneigenschaft zugreifen kann, 
um z.B. den geänderten Wert auszulesen und zu verwenden. Stichwort 
"Reflection" hab ich schon mal aufgeschnappt, komme aber nicht weiter.

Grüße, Alex
Gast #2391293
Lesenswert?

Hallo Arc Net

Danke für den Hinweis. Ausgehen von dem, was ich dort und auch so noch 
im Netz gefunde habe, heb ich ein bisschen probiert. Es geht, allerdings 
scheint das noch nicht der Weisheit letzter Schluss zu sein. Z.B. 
erscheint es mir "komisch", dass ich eine Methode von sender aufrufe, 
der ich dann sender übergebe. Auch kann man ja zur Laufzeit nicht 
wissen, ob ich das einfach in bool typecasten kann. Ich mach das jetz 
einfachm, weil ich weiß das die Property bool ist, aber sauber ist das 
doch so nicht, oder? Kannst Du mal bitte einen Blick darauf werfen und 
gegebenenfalls was bemängeln.
1
 private void On_PropertyChanged(object sender, PropertyChangedEventArgs e)
2
        {
3
            object IsOnline = sender.GetType().GetProperty(e.PropertyName).GetValue(sender,null);
4
            object SenderNo = sender.GetType().GetProperty("SenderNo").GetValue(sender, null);
5
            
6
            switch((int)SenderNo)
7
            {
8
                case 0:
9
                    if ((bool)IsOnline)
10
                    {
11
                        labelRadioStatus.Text = "online";
12
                        labelRadioStatus.BackColor = Color.Green;
13
                    }
14
                    else
15
                    {
16
                        labelRadioStatus.Text = "offline";
17
                        labelRadioStatus.BackColor = Color.Red;
18
                    }
19
                    break;
20
                case 1:
21
                    if ((bool)IsOnline)
22
                    {
23
                        labelRadioStatus.Text = "online";
24
                        labelRadioStatus.BackColor = Color.Green;
25
                    }
26
                    else
27
                    {
28
                        labelRadioStatus.Text = "offline";
29
                        labelRadioStatus.BackColor = Color.Red;
30
                    }
31
                    
32
                    break;
33
                default:
34
                    break;
35
            }

Danke, Alex
Gast #2392316
Lesenswert?

Hallo Christian,

ich schreibe an einer Windows Forms Anwendung. Das mit dem typecast 
hatte ich probiert. Was mir Probleme macht, ist der Zugriff auf die 
Eigenschaft mit Hilfe des e.PropertyName.
Also etwa so (natürlich syntaktisch völliger Unfug, aber zum 
Verständnis):

var o = sender as myClass;
... = o.(e.PropertyName);

Sozusagen anhand e.PropertyName schauen, welchen Typ e.PropertyName in 
myClass hat, Variable entsprechend deklarieren und dann den Wert aus der 
Klasseninstanz zuweisen.

Eine Frage noch. Wie verhält sich das bei der Datenbindung. Müssen da 
Datenquelle und Ziel vom selben Typ sein. In meinem Fall soll ja auf 
Änderung einer Bool-Variable hin ein Textfeld geändert werden.

Danke und Gruß, Alex
#2392560
Lesenswert?

Alex,

Ich würde das auch so wie bluppdidupp beschrieben hat machen!
Immerhin bist du in deiner App Herr über die Klassen und
kannst e.PropertyName auswerten und dann direkt auf die entspr. 
Properties
zugreifen.

Um Fehler zu vermeiden, empfehle ich Konstanten für die 
Eigenschaftsnamen
einzuführen.


public class MyClass : INotifyPropertyChanged
{
 ...

 public bool IsOnline
 {
   get { return this._isOnline; }
   set
   {
     if(this._isOnline != value)
     {
       this._isOnline = value;
       NotifyPropertyChanged(PropertyNameIsOnline);
     }
   }
 }
 private bool _isOnline;
 public const string PropertyNameIsOnline = "IsOnline";
 ....
}


dann kannst du in den event handlern oder anderen Funktionen drauf 
zugreifen:


if(e.PropertyName == MyClass.PropertyNameIsOnline)
{
  .....
}


Es liegt natürlich am Entwickler dafür zu sorgen, die Konstanten immer
aktuell zu halten!

zur Datenbindungs-Frage:
In deinem Fall änderst du Text und Farbe - also würde ich hier o.a. 
Methodik implementieren.
Bei Winforms Apps habe ich selten Databinding eingesetzt. Grad mal bei 
ComboBoxen oder einem Data-Grid.
Data Binding fetzt erst so richtig in WPF oder Silverlight Apps!
Dort setzt man dann Konvertoren ein, wenn die Typen nicht zusammen 
passen.

Grüße,
Christian
Gast #2392659
Lesenswert?

Hallo liebe Helfende,

am Ende werde ich das wohl so, wie voergeschlagen, machen. Ich hatte nur 
gelesen, dass man den Zugriff auf die Properties von sender im 
Eventhandler via Reflection macht und dachte, dass so machen zu müssen, 
weil es die saubere Lösung wäre. Ich hab auch in 'nem engl. Forum einen 
Thread gelesen, wo jemand das machen wollte, ohne String-Literale zu 
verwenden. Also kein
1
if(e.PropertyName == "bestimmterString")
Warum, weiß ich jetzt nicht mehr genau. Ich wollte es quasi ganz elegant 
machen, bzw. so, wie man das halt macht, wenn es den einen Königweg 
geben sollte, Scheuklappen sozusagen.

@blubbdidubb:

if (irgendeinObject is bool)

wenn ich das so machen wollte, müsste ich ja das object auf jeden 
möglichen Typ testen. Das wäre unter Umständen ziemlich länglich.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren