Пока идет
очередноеАвтор: Fortnum
Дата: 27.10.10
бурное обсуждение интерфейса INotifyPropertyChanged и системы свойств WPF, если честно, я поймал себя на мысли, что не осознаю на сей счет простого факта в части DependencyProperty. И пусть для кого-то это будет не новостью, но я настолько поражен своим "открытием", что должен высказаться. Биндиться к DependencyProperty мы можем? Можем. А INotifyPropertyChanged этот самый DependencyProperty реализует? Нет. То есть биндинг к DependencyProperty — это
особый случай биндинга. Но с этим фактом еще жить можно. Смотрим дальше.
Возьмем WPF-окно и посадим в его DataContext экземпляр элементарного класса ViewModel, который
не реализует интерфейс INotifyPropertyChanged:
public class ViewModel
{
public double Value { get; set; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
В окно посадим два TextBox'а, и прибиндим их к CLR-свойству датаконтекстного экземпляра этого ViewModel:
<Window
x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Vertical">
<TextBox Text="{Binding Value}"/>
<TextBox Text="{Binding Value}"/>
</StackPanel>
</Window>
Можете кинуть в меня тухлым помидором, но признаюсь, я бы ни за что не догадался, что биндинг при этом будет работать! Да, меняем значение в одном TextBox, меняется значение в другом!
PS. До сего момента из особых случаев биндинга я знал только
об автоматическом создании CollectionViewSource при биндинге к коллекциям разного рода, а также об
особой работе биндинга с интерфейсом IBindingList.
Здравствуйте, Fortnum, Вы писали:
F>А INotifyPropertyChanged этот самый DependencyProperty реализует? Нет.
И не надо. Реализовать должен объемлющий класс, а не само проперти. К тому же, для DependencyProperty, или же для предлагаемых мною "пинов" интерфейс, подобный INotifyPropertyChanged, должен иметь немного другой АПИ и семантику. Вместо строкового идентификатора должен мог бы приходить некий объект-идентити самого св-ва.
В этом плане очень хорошо продвинулась либа BLT. В ней возможно рантайм-создание эффективных аксессоров к обычным пропертям. На этих аксессорах я когда-то делал свой биндинг не для GUI, а от него — на GUI
, потрясающе удобно. Ну и внутренние контракты любой системы биндинга обычно куда как осмысленнее, чем INotifyPropertyChanged.
F>То есть биндинг к DependencyProperty — это особый случай биндинга. Но с этим фактом еще жить можно. Смотрим дальше.
Ну да, классы навроде Bind свои у WinForms и у WPF. Каждая библиотека биндинга по-своему особая.
F>Возьмем WPF-окно и посадим в его DataContext экземпляр элементарного класса ViewModel, который не реализует интерфейс INotifyPropertyChanged:
...
F>Можете кинуть в меня тухлым помидором, но признаюсь, я бы ни за что не догадался, что биндинг при этом будет работать! Да, меняем значение в одном TextBox, меняется значение в другом!
А почему он не должен работать? Ты же не знаешь, как оно внутре устроено. При чем тут именно INotifyPropertyChanged?
Могу указать как пример WinForms, в котором контролы, не имеющие своего проинициализированного экземпляра аналогичного DataContext, запрашивали его у контейнера сколь угодно вверх по цепочке. Подозреваю, что здесь аналогично. Дело в том, что INotifyPropertyChanged — это лишь один из способов сообщения об изменении св-ва, поддерживаемый конкретной системой биндинга. Есть еще несколько способов. А конкретный bind-адаптер строится по первому же найденному подходящему способу для конкретного объекта и св-ва.