WPF - привязка данных
Связывание данных - это механизм в приложениях WPF, который обеспечивает простой и легкий способ для приложений среды выполнения Windows отображать данные и взаимодействовать с ними. В этом механизме управление данными полностью отделено от способа передачи данных.
Связывание данных позволяет поток данных между элементами пользовательского интерфейса и объектом данных в пользовательском интерфейсе. Когда привязка установлена и данные или ваша бизнес-модель изменяются, она автоматически отражает обновления элементов пользовательского интерфейса и наоборот. Также можно выполнить привязку не к стандартному источнику данных, а к другому элементу на странице.
Привязка данных бывает двух типов - one-way data binding и two-way data binding.
Односторонняя привязка данных
При односторонней привязке данные привязываются от своего источника (то есть объекта, который хранит данные) к своей цели (то есть объекту, который отображает данные)
Давайте рассмотрим простой пример, чтобы подробно разобраться в односторонней привязке данных. Прежде всего, создайте новый проект WPF с именемWPFDataBinding.
Следующий код XAML создает две метки, два текстовых поля и одну кнопку и инициализирует их с некоторыми свойствами.
<Window x:Class = "WPFDataBinding.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local = "clr-namespace:WPFDataBinding"
mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height = "Auto" />
<RowDefinition Height = "Auto" />
<RowDefinition Height = "*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width = "Auto" />
<ColumnDefinition Width = "200" />
</Grid.ColumnDefinitions>
<Label Name = "nameLabel" Margin = "2">_Name:</Label>
<TextBox Name = "nameText" Grid.Column = "1" Margin = "2"
Text = "{Binding Name, Mode = OneWay}"/>
<Label Name = "ageLabel" Margin = "2" Grid.Row = "1">_Age:</Label>
<TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "2"
Text = "{Binding Age, Mode = OneWay}"/>
<StackPanel Grid.Row = "2" Grid.ColumnSpan = "2">
<Button Content = "_Show..." Click="Button_Click" />
</StackPanel>
</Grid>
</Window>
Текстовые свойства обоих текстовых полей привязаны к «Name» и «Age», которые являются переменными класса класса Person, который показан ниже.
В классе Person у нас всего две переменные Name и Age, а его объект инициализируется в MainWindow класс.
В коде XAML мы привязываемся к свойству Name и Age, но мы не выбрали, какому объекту принадлежит это свойство.
Более простой способ - присвоить объект DataContext свойства которого мы связываем в следующем коде C # в MainWindowconstructor.
using System.Windows;
namespace WPFDataBinding {
public partial class MainWindow : Window {
Person person = new Person { Name = "Salman", Age = 26 };
public MainWindow() {
InitializeComponent();
this.DataContext = person;
}
private void Button_Click(object sender, RoutedEventArgs e) {
string message = person.Name + " is " + person.Age;
MessageBox.Show(message);
}
}
public class Person {
private string nameValue;
public string Name {
get { return nameValue; }
set { nameValue = value; }
}
private double ageValue;
public double Age {
get { return ageValue; }
set {
if (value != ageValue) {
ageValue = value;
}
}
}
}
}
Давайте запустим это приложение, и вы сразу увидите в нашем MainWindow, что мы успешно связали имя и возраст этого объекта Person.
Когда вы нажимаете Show кнопку, имя и возраст отобразятся в окне сообщения.
Давайте изменим Имя и Возраст в диалоговом окне.
Если вы сейчас нажмете кнопку «Показать», снова отобразится то же сообщение.
Это связано с тем, что в коде XAML установлен односторонний режим привязки данных. Чтобы отображать обновленные данные, вам необходимо понимать двустороннюю привязку данных.
Двусторонняя привязка данных
При двусторонней привязке пользователь может изменять данные через пользовательский интерфейс и обновлять эти данные в источнике. Если источник изменяется, когда пользователь смотрит на представление, вы хотите, чтобы представление было обновлено.
Возьмем тот же пример, но здесь мы изменим режим привязки с одностороннего на двусторонний в коде XAML.
<Window x:Class = "WPFDataBinding.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local = "clr-namespace:WPFDataBinding"
mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height = "Auto" />
<RowDefinition Height = "Auto" />
<RowDefinition Height = "*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width = "Auto" />
<ColumnDefinition Width = "200" />
</Grid.ColumnDefinitions>
<Label Name = "nameLabel" Margin = "2">_Name:</Label>
<TextBox Name = "nameText" Grid.Column = "1" Margin = "2"
Text = "{Binding Name, Mode = TwoWay}"/>
<Label Name = "ageLabel" Margin = "2" Grid.Row = "1">_Age:</Label>
<TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "2"
Text = "{Binding Age, Mode = TwoWay}"/>
<StackPanel Grid.Row = "2" Grid.ColumnSpan = "2">
<Button Content = "_Show..." Click = "Button_Click" />
</StackPanel>
</Grid>
</Window>
Давайте снова запустим это приложение.
Он будет производить тот же результат -
Теперь изменим значения Name и Age -
Если сейчас нажать кнопку «Показать», отобразится обновленное сообщение.
Мы рекомендуем вам выполнить приведенный выше код в обоих случаях для лучшего понимания концепции.