Moin,
ich habe mal eine theoretische Frage zu einem Binding:
Ich habe eine View und ein ViewModel - in diesem gibt es eine Property MyProperty
vom Typ MyClass
.
MyClass sieht so aus (auszugsweise und aus'm Kopf getippt):
public class MyClass : INotifyPropertyChanged
{
public MyClass(int value)
{
Value = value;
}
private int _value;
public int Value
{
get {...}
set {...; OnPropertyChanged();}
}
public override string ToString()
{
return $"{Value} from ToString()";
}
#NotifyPropertyChanged-Member#
}
MyProperty
wird in der View z.B. an eine TextBox gebunden.
Durch den Standardconverter und dem Aufruf von ToString() steht in dieser dann z.B. "22 from ToString()".
Ändert sich jetzt der Value in MyProperty
, ändert sich natürlich nicht der Text in der Textbox mit.
Gibt es eine Möglichkeit - bei einem Binding an eine Klasse - das Binding an eine Property der Klasse zu delegieren?
Mir ist bewusst, dass man in der View auch MyProperty.Value
schreiben kann.
Hi ! Die Änderung siehst du nicht, weil OnPropertyChanged nach der Änderung nicht aufgerufen wird. Du musst dem View mitteilen, dass es Änderungen innerhalb der "nested properties" gab. Beispielsweise könntest du nach der Änderung MyProperty neu setzen.
Das geht nur dann, wenn der Value vom ViewModel geändert wird. MyProperty dann nochmal zu setzen finde ich allerdings unschön.
Ändert sich der Value von anderer Stelle aus (z.B. direkt von der MyClass aus) funktioniert der Workaround nicht.
Hi p!lle,
ich verstehe deine Frage nicht. Du willst den Wert eines ViewModel-Propertys anzeigen und bearbeiten, aber du willst nicht an das Property binden, weil das "unschön" ist? Kannst du das mal genauer erläutern?
Weeks of programming can save you hours of planning
1.Möglichkeit im Parent-ViewModel
private MyClass myClass;
public MyClass MyClass
{
get { return myClass; }
set
{
if ( myClass != null ) myClass.PropertyChanged -= MyClass_PropertyChanged;
myClass = value;
if ( myClass != null ) myClass.PropertyChanged += MyClass_PropertyChanged;
RaisePropertyChanged();
}
}
private void MyClass_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
{
RaisePropertyChanged( nameof( MyClass ) );
}
1.Möglichkeit
public class MyClass : ObservableObject
{
private string _value;
public string Value
{
get { return _value; }
set
{
_value = value;
RaisePropertyChanged();
RaisePropertyChanged( nameof( DisplayText ) );
}
}
public override string ToString()
{
return $"{Value} from ToString()";
}
public string DisplayText
{
get
{
return ToString();
}
}
}
Und dann das Binding der TextBox eben an MyCLass.DisplayText
Danke für eure Antworten. =)
Es geht im Groben um die Vereinfachung (um nicht immer Class.Property
schreiben zu müssen), wenn man an eine Klasse bindet, die einen anderen Wert kapselt (aus welchen Gründen auch immer).
Auf die Frage, ob das geht, bin ich aufgrund diverser Experimente mit der WPFLocalizationExtension gekommen.
Der 'Wunsch' war im Endeffekt z.B. ein Attribut zu haben, in dem man für eine Klassen sagen kann:
"Wenn an diese Klasse gebunden wird, dann nutze standardmäßig die Property XYZ." - gibt ja heutzutage einige Schweinereien, die man machen kann... :evil:
=)
(Die ToString()-Überladung in meinem Beispiel war wahrscheinlich schlecht gewählt.)
gibt ja heutzutage einige Schweinereien, die man machen kann... :evil:
Aber das heißt ja nicht, daß man es auch machen muß 😃
Ich halte das jedenfalls für keine besonders gute Idee. Schon allein weil der XAML-Quelltext nicht mehr lesbar ist, ohne den Quelltext zu kennen, der die "Property-Umleitungen" definiert. Und so umständlich ist es ja auch nicht, den Namen des Propertys zu schreiben, an das man binden möchte.
Weeks of programming can save you hours of planning