DataContext służy do wiązania danych. Jest to jakby wskaźnik na klasę z której chcesz wyciągać jakieś dane. Możesz użyć bindingu aby aktualizować dane w klasie, kiedy właściwość kontrolki się zmienia (BindingMode = OneWayToSource) lub aktualizować dane w kontrolce kiedy właściwość w klasie sie zmienia (BindingMode = OneWay) lub oba naraz (BindingMode = TwoWay).
Dobrą cechą jest to, że każda kontrolka-dziecko będzie dziedziczyć DataContext po rodzicach.
Ale tu nachodzi nas myśl: Kiedy kontrolka wie, że ma się zaktualizować? DataContext korzysta z interfejsu INotifyPropertyChanged. Za pomocą eventu w nim zawartego możemy poinformować wszystkie obiekty obserwujące naszą właściwość o tym, że wartość jaką reprezentuje zmieniła się.
Na początku stwórzmy sobie projekt MainWindow.xaml, MainWindow.xaml.cs.
Dodajmy teraz pustą klasę MainWindowView. ta klasa będzie reprezentowała nasz DataContext i z niej będziemy tworzyć wszystkie właściwości do Bindingu.

Mamy więc naszą klasę do której będziemy bindować. Zwróć uwagę, na przestrzeń nazw w jakiej znajduje się Twój MainWindowView
Kopiuj
namespace testowa
{
class MainWindowView
{
}
}
Kolejnym krokiem będzie zastąpienie obecnej wartości DataContext na naszą klasę MainWindowView. Otwórz MainWindow.xaml. Jeżeli twoja klasa znajduje się w innej przestrzeni nazw niż kontrolka możesz dodać nową przestrzeń nazw w ten sposób:
Kopiuj
xmlns:NowyTagDlaPrzestrzeniNazw="clr-namespace:testowa.MynameSpace"
Gdy już wiemy, że kod XAML będzie widział naszą klasę ustawmy wartość dla DataContext:
Kopiuj
<Grid>
<Grid.DataContext>
<local:MainWindowView x:Name="hMainWindowView"/>
</Grid.DataContext>
</Grid>
Przy okazji dodajmy od razu 2 TextBoxy:
Kopiuj
<StackPanel>
<TextBox />
<TextBox />
</StackPanel>
Teraz chcielibyśmy zrobić tak:
Pierwszy **TextBox **będzie zapisywał we właściwości to, co do niego wpiszemy.
Drugi **TextBox **będzie odczytywał zmiany we właściwości.
Zabierzmy się więc do utworzenia takowej właściwości: Do klasy **MainWindowView **zaimplementuj interfejs INotifyPropertyChanged, za pomocą którego będziesz informował o zmianie wartości właściwości:

następnie utwórzmy właściwość typu string:
csharp public string Tekst;
I tu powstaje problem, ponieważ kiedy właściwość się zmienia musimy powiadomić o tej zmianie metodą OnPropertyChanged().
Rozwiązanie:
- Stworzymy właściwość "text" przechowującą wartość +
- Stworzymy właściwość "Text" za pomocą której będziemy odczytywać i zapisywać do poprzedniej właściwości
Kopiuj
private string tekst;
public string Tekst
{
get
{
return tekst;
}
set
{
tekst = value;
}
}
jedyne co nam teraz pozostało to użycie metody z interfejsu** INotifyPropertyChanged **od razu po tym kiedy właściwość zmieniła wartość (pamiętaj, że wartość zmienia się w naszej drugiej właściwości, pierwsza ją tylko przechowuje)
csharp OnPropertyChanged("Tekst");
teraz możemy zbindować **Property ** do naszego DataContext. Składnia jest następująca:
Kopiuj
<TextBox Text="{Binding Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
Efekt jest następujący:

Ale my przecież chcemy użyć właściwości z tej klasy, a nie tej klasy. Aby odwołać się do właściwości musimy użyć ścieżki tzn:
Kopiuj
<TextBox Text="{Binding Path=Tekst, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
Od teraz kiedy zmieni się wartość właściwości "Tekst" zmieni się właściwość "Text" w kontrolce
Teraz kiedy wiesz jak to działa możemy zająć się twoim problemem:
- Stwórz swoje klasy w MainWindowView jako właściwości
- Pamiętaj, że Twoje klasy też muszą implementować interfejs INotifyPropertyChanged
- Aby odnosić się do elementów klasy spójrz na ten przykład i odezwij się jak będziesz miał jakiś problem
MainWindoowView:
Kopiuj
public class MainWindowView : INotifyPropertyChanged
{
public MainWindowView()
{
MyDog = new Dog("pupilek");
MyCat = new Cat("kiciuś");
}
#region ProperyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string PropertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
#endregion
private Dog myDog;
public Dog MyDog
{
get
{
return myDog;
}
private set
{
myDog = value;
OnPropertyChanged("MyDog");
}
}
private Cat myCat;
public Cat MyCat
{
get
{
return myCat;
}
private set
{
myCat = value;
OnPropertyChanged("MyCat");
}
}
}
public class Animal : INotifyPropertyChanged
{
public Animal(string Name)
{
this.Name = Name;
}
#region ProperyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string PropertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
#endregion
private string name;
public string Name
{
get
{
return name;
}
private set
{
name = value;
OnPropertyChanged("Name");
}
}
}
public class Dog : Animal, INotifyPropertyChanged
{
public Dog(string Name) : base(Name)
{
}
}
public class Cat : Animal, INotifyPropertyChanged
{
public Cat(string Name) : base(Name)
{
}
}
Kod MainWindow.xaml
Kopiuj
<TextBox Text="{Binding Path=MyDog.Name, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Text="{Binding Path=MyCat.Name, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
Jeżeli coś nie jasne pytaj