Wieso funktioniert meine WPF-Bindung zwischen Textbox und Property nicht?

1 Antwort

Wieso nimmst du das Binding im Code vor und nicht in der XAML-View?

Die View könnte so aussehen (die hierfür irrelevanten Attribute lasse ich einmal weg):

<Window xmlns:local="clr-namespace:ExampleProject">
  <Window.DataContext>
    <local:ViewModel />
  </Window.DataContext>
  <StackPanel>
    <TextBox Text="{Binding LabelContent, UpdateSourceTrigger=PropertyChanged}" />
    <Label Content="{Binding LabelContent}" />
  </StackPanel>
</Window>

Wichtig ist hier zum Einen, dass der Datenkontext auf der ViewModel-Klasse liegt und zum anderen der UpdateSourceTrigger auf PropertyChanged.

Im ViewModel muss das Property (ich habe es für die Demonstration LabelContent genannt) bei Änderung ein PropertyChanged-Event werfen.

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace ExampleProject
{
  public class ViewModel : INotifyPropertyChanged
  {
    private string _labelContent;

    public string LabelContent
    {
      get => _labelContent;
      set
      {
        if (_labelContent != value)
        {
          _labelContent = value;
          OnPropertyChanged(nameof(LabelContent));
        }
      }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string name = null)
    {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
  }
}

maga55 
Beitragsersteller
 19.10.2020, 14:59

Naja, das besagt die Aufgabenstellung, das ich diese Bindung im Code-Behind machen soll. Es ist eine Aufgabe von meinem Lehrer. Aber die Schritte, die du zeigst, habe ich doch eigentlich auch gemacht? Also ich habe bei meiner Property INotifyPropertyChanged implementiert.

regex9  19.10.2020, 15:26
@maga55

Beides lässt sich aus dem obigen Text nicht herleiten. Aber es funktioniert ebenso:

1) Das View (wieder nur der relevante Teil):

<StackPanel>
  <TextBox x:Name="tb1" />
  <Label x:Name="studentAnzeige" />
</StackPanel>

2) Der Konstruktor in der xaml.cs (ich diesmal mal einfach das ViewModel weg):

InitializeComponent();

// your code ...        

An deinem Code braucht keine Anpassung für die Funktionalität vorgenommen werden.

3) Die Student-Klasse:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace ExampleProject
{
  public class Student : INotifyPropertyChanged
  {
    private int _matriculationNumber;

    public Student(string firstname, string lastname, int matriculationNumber)
    {
      // ...
    }

    public int Matrikelnummer
    {
      get => _matriculationNumber;
      set
      {
        if (_matriculationNumber != value)
        {
          _matriculationNumber = value;
          OnPropertyChanged(nameof(Matrikelnummer));
        }
      }
    }

    // property changed implementation ...
  }
}

Den Namen des Properties würde ich noch anpassen (einen englischen Bezeichner verwenden).