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 
Fragesteller
 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.

0
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).

0