Laden...

Data Binding anscheinend korrekt, trotzdem werden Werte nicht aus ViewModel in die View übernommen.

Erstellt von Stephan Gertens vor 12 Jahren Letzter Beitrag vor 11 Jahren 1.416 Views
S
Stephan Gertens Themenstarter:in
5 Beiträge seit 2011
vor 12 Jahren
Data Binding anscheinend korrekt, trotzdem werden Werte nicht aus ViewModel in die View übernommen.

Guten Abend Leute!

Da mir beim letzten Mal so super geholfen wurde, melde ich mich mit meinem nächsten Problem ebenfalls bei euch. Wäre über jegliche Hilfe sehr dankbar.

Es geht um das Binden eines Sliders. Ich habe in meiner View ein Attribut "sliderVisibility", hier reduziert auf das Wesentliche:


public class ViewModel : INotifyPropertyChanged
{ 
   ...
   public String sliderVisibility {get; set;}
   ...

   public ViewModel() 
   {
   sliderVisibility = "Visible";
   }
 
   ...
   public Methode()
   {
   sliderVisibility = "Hidden";
   }
}

In meinem ViewModel setze ich das Attribut im Konstruktor auf "Visible". In einer Methode, die drumherum einwandfrei funktioniert (auch sämtliche andere Bindings), setze ich das Attribut zur Laufzeit auf "Hidden". Aber die Änderung zur Laufzeit wird nicht von der View aktualisiert.

Ändere ich im Konstruktor die Initialisierung auf "Hidden", ist der Slider weg, also scheint das Data Binding ja auch zu funktionieren. Im XAML-Code binde ich mich im Slider wie folgt:


...
<Slider Name="Beispiel" Visibility="{Binding SliderVisibility}/>
...

StaticResource des ViewModels befindet sich im DataContext.

Also, Zusammenfassung: DataBinding scheint zu funktionieren, jedoch werden die Werte aus dem ViewModel in die View nicht aktualisiert. Natürlich habe ich schon sämtliche Modes ausprobiert, das INotifyPropertyChanged ist ebenfalls drin (wie auch oben im Beispiel) und wie gesagt: alle anderen Bindings funktionieren mit dem ViewModel einwandfrei.

Ich bin noch relativ unerfahren im Umgang mit WPF und wette, ihr seht den Fehler sofort. Mich hat es heute leider den ganzen Tag gekostet 😦

vielen Dank soweit,
Stephan

3.430 Beiträge seit 2007
vor 12 Jahren

Hallo,

du hast zwar das INotifyPropertyChanged Interface implementiert, was schon richtig ist.
Du musst es aber auch bei jeder Änderung aufrufen.

D.h. im Setter von der SliderVisiblity musst du den Wert des Feldes setzen und das PropertyChanged Event auslösen. Als Parameter gibst du den Namen des Property mit welches sich geändert hat.

Damit wir der Wert dann in die GUI übernommen.

Zudem ist es nit wirklich praktisch wenn du einen String für die Visiblity Eigenschaft verwendest. Entweder du nimmst dir einen Bool Wert (Visible = false oder true) und bindest diesen dann mit einen Converter, oder du verwendest direkt den Visiblity Enum

Gruß
Michael

6.902 Beiträge seit 2009
vor 12 Jahren

Hallo Stephan Gertens,

wie Michael schon geschrieben hat, muss auch das PropertyChanged-Ereignis aufgerufen werden. Also sollte das Property sliderVisibility so implementiert sein:


private Visibility _sliderVisibility;
public Visibility SliderVisiblity
{
    get { return _sliderVisiblity; }
    set
    {
        if (_sliderVisiblity == value) return;

        _sliderVisiblity = value;
        this.OnPropertyChanged("SliderVisiblity");
    }
}

private void OnPropertyChanged(string propName)
{
    var handler = this.PropertyChanged;
    if (handler != null)
        handler(this, new PropertyChangedEventArgs(propName));
}

Da nun ein ähnliches Muster in allen ViewModel vorhanden ist, ist es praktisch wenn du dazu eine Basisklasse erstellst, inder das OnPropertyChanged als protected-Member vorhanden ist. Das erspart dass immer wieder der gleiche Code geschrieben wird. Noch einen Schritt weiter gegangen und du nimmst dann ein fertiges MVVM-Framework, denn diese bieten solche Funktionalitäten schon an. Emfpehlungungen welchen findest du über die Forensuche.

Den Typ hab ich auch von String nach Visibility geändert.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

S
Stephan Gertens Themenstarter:in
5 Beiträge seit 2011
vor 12 Jahren

Wow,

ihr seid klasse, vielen Dank!

Grüße und schönen Abend,
Stephan

I
36 Beiträge seit 2013
vor 11 Jahren

Hi,

ich habe ein recht ähnliches Problem:

bei mir ist aber leider der handler == null, d.h. ich rufe zwar PropertyChanged auf, ich prüfe sogar, ob ich mit this.GetType().GetProperty(propertyName) das Property von meinem RaisePropertyChanged(String) bekomme, aber das hilft halt nicht, wenn der handler, den das interessieren sollte Null ist.

Muss ich, um das ViewModel zu binden mehr machen, als
.DataContext = ViewModel und .ItemsSource = ViewModel.Property ?

Mein Problem ist nun, die bei der Initialisierung voreingestellten Werte werden so dargestellt - nur wenn ich diese Ändere, wird die Änderung nicht übernommen.

Vielleicht mag/kann mir ja wer helfen. Vielen Dank im Voraus.

++++ Tag ein, Tag aus: HTML-Programmierer beklagt monotone Arbeit ++++
++++ Ein Witz auf seine Kosten: Masochist kann nur gequält lächeln ++++
++++ Nichts dran: Model leugnet Magersucht ++++

I
36 Beiträge seit 2013
vor 11 Jahren

Hallo,

mein vorheriger Beitrag hat sich erledigt. Offensichtlich muss man nichts anderes tun.

Es muss sich nur mal VisualStudio vernünftig aufhängen, hart abgewürgt werden, das Projekt neucompilieren und dann funktioniert das auch genau so (wie es ohnehin sollte) ...

Vielen Dank an alle die versucht haben sollten das Problem nachzuvollziehen.

++++ Tag ein, Tag aus: HTML-Programmierer beklagt monotone Arbeit ++++
++++ Ein Witz auf seine Kosten: Masochist kann nur gequält lächeln ++++
++++ Nichts dran: Model leugnet Magersucht ++++