INotifyPropertyChanged vs. DependencyProperty
От: Fortnum  
Дата: 29.10.10 15:46
Оценка:
Пока идет очередное
Автор: 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.
Re: INotifyPropertyChanged vs. DependencyProperty
От: vdimas Россия  
Дата: 29.10.10 17:21
Оценка:
Здравствуйте, 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-адаптер строится по первому же найденному подходящему способу для конкретного объекта и св-ва.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.