Ответ
В WPF механизм привязки данных (Data Binding) поддерживает несколько режимов (Mode), которые определяют направление потока данных. Выбор режима критически важен для корректного поведения UI.
Доступные режимы (System.Windows.Data.BindingMode):
| Режим | Назначение | Типичное использование |
|---|---|---|
OneWay |
Данные идут от источника к цели. Изменения в цели (UI) не обновляют источник. | Отображение текста, изображений, «только для чтения». |
TwoWay |
Двусторонняя привязка. Изменения в источнике и цели синхронизируются. | Элементы ввода: TextBox, Slider, CheckBox. |
OneTime |
Привязка происходит один раз при инициализации. Последующие изменения в источнике игнорируются. | Статические данные, которые не меняются во время работы (например, версия приложения). |
OneWayToSource |
Обратный OneWay. Данные идут от цели к источнику. |
Когда нужно обновить источник на основе значения UI-элемента, который сам не отображает данные (например, Slider как элемент управления). |
Default |
Режим по умолчанию, который зависит от свойства зависимости цели. Для TextBlock.Text это OneWay, для TextBox.Text — TwoWay. |
Практические примеры в XAML:
<Window x:Class="BindingExample.MainWindow" ...
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<StackPanel>
<!-- OneWay (по умолчанию для TextBlock) -->
<TextBlock Text="{Binding CurrentTime, StringFormat='Текущее время: {0:HH:mm:ss}'}"/>
<!-- TwoWay (обязателен для элементов ввода) -->
<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<CheckBox IsChecked="{Binding IsAgreed, Mode=TwoWay}" Content="Согласен"/>
<Slider Value="{Binding Volume, Mode=TwoWay}" Minimum="0" Maximum="100"/>
<!-- OneTime -->
<TextBlock Text="{Binding AppVersion, Mode=OneTime}"/>
<TextBlock Text="{Binding Source={x:Static sys:DateTime.Now},
StringFormat='Дата запуска: {0:dd.MM.yyyy}', Mode=OneTime}"/>
<!-- OneWayToSource -->
<!-- Источник SelectedValue обновляется, когда меняется выбор в ListBox -->
<ListBox ItemsSource="{Binding Items}"
SelectedValue="{Binding SelectedItem, Mode=OneWayToSource}"/>
</StackPanel>
</Window>
Ключевой аспект для TwoWay и OneWayToSource:
Чтобы изменения, инициированные UI, передавались обратно в источник данных (например, в ViewModel), источник должен реализовывать интерфейс INotifyPropertyChanged.
public class MainViewModel : INotifyPropertyChanged
{
private string _userName;
public string UserName
{
get => _userName;
set
{
if (_userName != value)
{
_userName = value;
OnPropertyChanged(); // Это уведомляет UI об изменении
}
}
}
// ... реализация INotifyPropertyChanged и другие свойства
}
UpdateSourceTrigger: Для TwoWay привязок важно свойство UpdateSourceTrigger, которое определяет, когда обновлять источник. По умолчанию для TextBox.Text это LostFocus. Установка PropertyChanged (как в примере выше) заставляет источник обновляться при каждом нажатии клавиши, что часто используется для live-поиска или валидации.