Привязка данных в Windows Forms
От: Сергей Тепляков США http://sergeyteplyakov.blogspot.com/
Дата: 30.12.08 16:29
Оценка: 510 (16) +2
Статья:
Привязка данных в Windows Forms
Автор(ы): Сергей Тепляков
Дата: 28.12.2008
Основная задача приложений Windows Forms – манипулирование данными. В определенный момент времени приложение получает данные из некоторого источника, отображает их пользователю, пользователь изменяет данные, затем измененные данные помещаются в источник (в тот же самый или иной). В некоторых приложениях может не быть некоторых из вышеперечисленных этапов, но в целом эта картина характерна для большинства приложений.
В приложении, работающем с данными, существует логическая взаимосвязь между уровнем данных и представлением, хотим мы этого или нет. Вопрос в том, сколько рутинной работы ложится на ваши плечи. Механизм привязки данных в Windows Forms в значительной степени упрощает создание приложений, работающих с данными. Понимание основных концепций, на которых строится привязка данных, может в значительной степени упростить построение таких приложений, а также помочь в решении различных проблем, которые неизменно преследуют каждого разработчика.


Авторы:
Сергей Тепляков

Аннотация:
Основная задача приложений Windows Forms – манипулирование данными. В определенный момент времени приложение получает данные из некоторого источника, отображает их пользователю, пользователь изменяет данные, затем измененные данные помещаются в источник (в тот же самый или иной). В некоторых приложениях может не быть некоторых из вышеперечисленных этапов, но в целом эта картина характерна для большинства приложений.
В приложении, работающем с данными, существует логическая взаимосвязь между уровнем данных и представлением, хотим мы этого или нет. Вопрос в том, сколько рутинной работы ложится на ваши плечи. Механизм привязки данных в Windows Forms в значительной степени упрощает создание приложений, работающих с данными. Понимание основных концепций, на которых строится привязка данных, может в значительной степени упростить построение таких приложений, а также помочь в решении различных проблем, которые неизменно преследуют каждого разработчика.
Re: Привязка данных в Windows Forms
От: WaSh http://kxlm.blogspot.com/
Дата: 03.01.09 18:18
Оценка: 2 (1)
Не запоздалая ли статья-то ??? Да еще и в печатном журнале только...

Уже давно пора написать что-то подобное для WPF с учетом новшевств 3.5 SP1 (чтоб было всё в одном месте).
Думаю, было бы актуальнее...
... << RSDN@Home 1.2.0 alpha 4 rev. 1108>>
блог http://kxlm.blogspot.com/
Re[2]: Привязка данных в Windows Forms
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 04.01.09 08:18
Оценка: :)
Здравствуйте, WaSh, Вы писали:

WS>Уже давно пора написать что-то подобное для WPF с учетом новшевств 3.5 SP1 (


напиши
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[2]: Привязка данных в Windows Forms
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 04.01.09 16:38
Оценка:
Здравствуйте, WaSh, Вы писали:

WS>Не запоздалая ли статья-то ??? Да еще и в печатном журнале только...


WS>Уже давно пора написать что-то подобное для WPF с учетом новшевств 3.5 SP1 (чтоб было всё в одном месте).

WS>Думаю, было бы актуальнее...

Ты считаешь, что после выхода WPF все перестали писать WinForms приложения?
Лично я в этом сомневаюсь...
Промышленная разработка ПО вещь крайне инерционная...
К тому же сейчас крайне мало коммерческих компонентов WPF (посмотри на тот же DevExpress). Поэтому мир WinForms будет жить еще долго, очень долго
Re[3]: Привязка данных в Windows Forms
От: WaSh http://kxlm.blogspot.com/
Дата: 04.01.09 16:58
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Здравствуйте, WaSh, Вы писали:


WS>>Не запоздалая ли статья-то ??? Да еще и в печатном журнале только...


WS>>Уже давно пора написать что-то подобное для WPF с учетом новшевств 3.5 SP1 (чтоб было всё в одном месте).

WS>>Думаю, было бы актуальнее...

ST>Ты считаешь, что после выхода WPF все перестали писать WinForms приложения?

ST>Лично я в этом сомневаюсь...
ST>Промышленная разработка ПО вещь крайне инерционная...
ST>К тому же сейчас крайне мало коммерческих компонентов WPF (посмотри на тот же DevExpress). Поэтому мир WinForms будет жить еще долго, очень долго
Не спорю...
Но на то, что "сейчас крайне мало коммерческих компонентов WPF" и вообще WPF мало используется, влияет отсутствие подобных статей...
... << RSDN@Home 1.2.0 alpha 4 rev. 1108>>
блог http://kxlm.blogspot.com/
Re[4]: Привязка данных в Windows Forms
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 04.01.09 17:26
Оценка:
Здравствуйте, WaSh, Вы писали:

WS>Не спорю...

WS>Но на то, что "сейчас крайне мало коммерческих компонентов WPF" и вообще WPF мало используется, влияет отсутствие подобных статей...

Тебе же уже предложили восполнить этот досадный пробел. Не хватает статей — вперед за перо!

Ну а рассматривать влияние статей (причем именно русскоязычных) о WPF и наличие коммерческих компонентов вообще забавно, причем здесь одно к другому На английском доступно масса материала по WPF вообще и по привязке данных в частности!
Это что получается, DevExpress не решается выпускать дополнительные компоненты только из-за того, что мало русскоязычных статей?
Re[3]: Привязка данных в Windows Forms
От: AK85 Беларусь  
Дата: 09.01.09 12:39
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>К тому же сейчас крайне мало коммерческих компонентов WPF (посмотри на тот же DevExpress). Поэтому мир WinForms будет жить еще долго, очень долго


Не вижу логики. Думаю это как раз показатель более совершенной системы, сторонние контролы практически не нужны.
Подход DM-V-VM мне кажется самым логичным и правильным способом работы с гуями.
А у сторонних разработкиков можно покупать только наборы стилей.
Re[4]: Привязка данных в Windows Forms
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 09.01.09 15:25
Оценка: -1
Здравствуйте, AK85, Вы писали:

ST>>К тому же сейчас крайне мало коммерческих компонентов WPF (посмотри на тот же DevExpress). Поэтому мир WinForms будет жить еще долго, очень долго


AK>Не вижу логики. Думаю это как раз показатель более совершенной системы, сторонние контролы практически не нужны.

AK>Подход DM-V-VM мне кажется самым логичным и правильным способом работы с гуями.
AK>А у сторонних разработкиков можно покупать только наборы стилей.

Это вы сейчас о чем?
Я всего лишь писал об актуальности тематики данной статьи для программиста, аргументируя это тем, что на данный момент большая часть приложений создается с использованием именно технологии Windows Forms. Кроме того, была замечена некомпетентность многих моих коллег в этом вопросе, отсюда и возникло желание в написание этой статьи.
При этом я не коим образом не собираюсь спорить о том, какая технология лучше или хуже.
Поэтому, о чем вы пишите, для меня совершенно не понятно?
Вероятно вы не совсем поняли суть нашего диалога
Re: Привязка данных в Windows Forms
От: adontz Грузия http://adontz.wordpress.com/
Дата: 26.01.09 18:55
Оценка:
Здравствуйте, Сергей Тепляков, Вы писали:

После прочтения статьи, захотелось почитать Тома Кленси.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: Привязка данных в Windows Forms
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 26.01.09 21:33
Оценка:
Здравствуйте, adontz, Вы писали:

A>После прочтения статьи, захотелось почитать Тома Кленси.


Кстати, рекомендую. Серьезный автор.
Re: Привязка данных в Windows Forms
От: ov  
Дата: 28.01.09 05:07
Оценка:
СТ>Статья:
СТ>Привязка данных в Windows Forms
Автор(ы): Сергей Тепляков
Дата: 28.12.2008
Основная задача приложений Windows Forms – манипулирование данными. В определенный момент времени приложение получает данные из некоторого источника, отображает их пользователю, пользователь изменяет данные, затем измененные данные помещаются в источник (в тот же самый или иной). В некоторых приложениях может не быть некоторых из вышеперечисленных этапов, но в целом эта картина характерна для большинства приложений.
В приложении, работающем с данными, существует логическая взаимосвязь между уровнем данных и представлением, хотим мы этого или нет. Вопрос в том, сколько рутинной работы ложится на ваши плечи. Механизм привязки данных в Windows Forms в значительной степени упрощает создание приложений, работающих с данными. Понимание основных концепций, на которых строится привязка данных, может в значительной степени упростить построение таких приложений, а также помочь в решении различных проблем, которые неизменно преследуют каждого разработчика.


прочитал статью и задумался: насколько неудобными средствами порой приходиться оперировать. привязать форму к объекту? пишем код. привязать объект к форме? пишем код. не хотим больше писать код привязки — опять пишем код, да такой, что без поллитра не разберешься.

я уже скоро год как разрабатываю программы для MacOS, тамошний фреймворк Cocoa тоже умеет делать биндинг данных. интереса ради решил повторить пример с книгами из статьи — сделал почти весь мышкой. клавиатуру трогал только чтобы названия полей вписать.

там есть типовые контроллеры для привязки объектов, массивов, деревьев итп. указываешь тип хранимого объекта, привязываешь практически любой контрол и говоришь с каким из полей объекта он будет связан. все — мышкой. вместро хранимого объекта можно использовать словарь — даже класс данных описывать не придется. вещи типа главной и второстепенной таблицы (авторы — книги) делаются на раз: создаются два контроллера массивов, один привязывается к выбранному элементу другого.

если привязываешься к массиву данных, то становятся доступными аттрибуты аггрегирования — можно привязать текстовое поле к массиву и попросить его отображать кол-во записей в массиве. или сумму, среднее, минимум, максимум итп. мелочи, в принципе... но насколько все становится проще. особенно учитывая то, что все делается мышкой — код писать не надо (он и "автоматически" не пишется, в отличие от "делания мышкой" в студии).

механизм, лежащий в основе этого всего, достаточно прост. базовый объект, от которого все наследуются, позволяет:
1. поменять значение проперти по ее имени
2. подписаться на уведомления о таких изменениях какого-либо объекта
и то и другое осуществимо и в дотнете, но не без геморроя. думаю, фреймворку к пятому нам-таки будет предложен более-менее нормальный механизм биндинга

З.Ы.: статья-то хорошая... а вот технология — не очень.
З.З.Ы: если вдруг кому стало интересно как это делается в Cocoa
Re[2]: Привязка данных в Windows Forms
От: andrex Украина  
Дата: 28.01.09 10:48
Оценка:
Здравствуйте, ov, Вы писали:

ov>и то и другое осуществимо и в дотнете, но не без геморроя. думаю, фреймворку к пятому нам-таки будет предложен более-менее нормальный механизм биндинга


Вряд ли. На осеннем PDC небыло ни одного доклада посвященного WinForms. Доработок каких то уже давно не видно и о новинках ничего не слышно. Похоже MS забили на винформс в угоду WPF.
С одной стороны WPF более правильный путь, но с другой, например, в моем случае аппаратное обеспечение большинства клиентов не позволяет использовать WPF для разработки приложений.
... << RSDN@Home 1.2.0 alpha rev. 788>>
Я бы изменил мир — но Бог не даёт исходников...
Re[3]: Привязка данных в Windows Forms
От: ov  
Дата: 28.01.09 10:51
Оценка:
ov>>и то и другое осуществимо и в дотнете, но не без геморроя. думаю, фреймворку к пятому нам-таки будет предложен более-менее нормальный механизм биндинга
A>С одной стороны WPF более правильный путь, но с другой, например, в моем случае аппаратное обеспечение большинства клиентов не позволяет использовать WPF для разработки приложений.

в Cocoa биндинг никак не завязан на интерфейс. вообще. интерфейс лишь пользуется этой возможностью фреймворка, не более того. если майкрософт на уровне класса System.Object это сделает — это можно будет использовать и в винформсе и в WPF и где угодно.
Re[4]: Привязка данных в Windows Forms
От: drol  
Дата: 29.01.09 23:28
Оценка:
Здравствуйте, ov, Вы писали:

ov>в Cocoa биндинг никак не завязан на интерфейс.


Дык и в .NET практически аналогично. Механизмы связанные с обсуждаемым binding'ом только живут в сборках WPF ( + второй "экземпляр" в WWF ), но от UI им особо-то ничего и не нужно. В принципе можно использовать везде где хочется, только понимать механику надо, разумеется А так... Лишь бы target-свойство было DependencyProperty (и, соответственно, target-объект — наследником DependencyObject). Source же вообще может быть кем/чем/где угодно.

Конечно, хочется всё это прямо в язык запихать, но, полагаю, "малой кровью" не получится. Вообще надо будет подумать на досуге, как бы это провернуть с минимальными "потерями"... Ну а для начала, хотя бы просто отпилить всё это добро от WPF/WWF, и сделать нормальный более-менее универсальный механизм в том же стиле, что существует сейчас.
Re: Привязка данных в Windows Forms
От: Sinix  
Дата: 30.01.09 02:28
Оценка: 2 (1)
Доброго дня вам!

По ходу у меня становится традицией отписываться на статьи...

В нарушение традициии эта приятно порадовала — умеют же если захотят. Как всегда — пустые придирки к коду. Ничего серьёзного — это ж сампл, не продакшн. Не обращяйте внимания и пишите ещё

1) Мелочь:
public event EventHandler<EventArgs> AuthorChanged;

Зачем здесь генерик-версия? Кстати, правило хорошего тона — заодно реализовать INotifyPropertyChanged.

2) Совсем пустая придирка:
if (AuthorChanged != null)
  AuthorChanged(this, EventArgs.Empty);

Выносится в отдельный метод. Да, проверка на нулл может не сработать при многопоточности. Перед проверкой кэшируйте в локальной переменной.

3) Ещё мелочь:
bookInfo.AuthorChanged += (s, e) => 
{
  authorTextBox.Text = ((BookInfo)s).Author;
};

Где отписка от событий? Или сущности буду жить меньше формы?

4) И ещё:
public CustomBinder(Control control, string controlPropertyName,
                 object dataSource, string dataSourcePropertyName)
{
...
}

Во-первых, поаккуратнее с исключениями в конструкторе — лучше Factory сделать. Во-вторых сначала стоит проверить на свойства сорс и таргет, и только потом подписываться на события. Опять, где отписка?И почему CustomBinder не IDisposable?

5) А кто лайфтаймом биндингов управлять будет? Не, я понимаю, что оно будет жить вечно...
  private void Bind()
  {
    CustomBinder authorPropertyManager = 
      new CustomBinder(authorTextBox, "Text", bookInfo, "Author");
    CustomBinder titlePropertyManager = 
      new CustomBinder(titleTextBox, "Text", bookInfo, "Title");
    CustomBinder isbnPropertyManager = 
      new CustomBinder(isbnTextBox, "Text", bookInfo, "ISBN");
    CustomBinder pageCountPropertyManager = 
      new CustomBinder(pageCountTextBox, "Text", bookInfo, "PageCount");
    CustomBinder publisherPropertyManager = 
      new CustomBinder(publisherTextBox, "Text", bookInfo, "Publisher");
  }


Дальше есть ещё пара мелких косяков, наподобие непроверки IndexOf(...) на -1, если интересно — найдёте сами.

Удачи!
Re[2]: Привязка данных в Windows Forms
От: adontz Грузия http://adontz.wordpress.com/
Дата: 30.01.09 04:00
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Выносится в отдельный метод. Да, проверка на нулл может не сработать при многопоточности. Перед проверкой кэшируйте в локальной переменной.


Проверка на null нафиг не нужна, делегаты неизменяемые объекты.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Привязка данных в Windows Forms
От: Sinix  
Дата: 30.01.09 07:05
Оценка:
Здравствуйте, adontz, Вы писали:

A>Проверка на null нафиг не нужна, делегаты неизменяемые объекты.


Ууу. Не читали вы Рихтера

//есть подписчик
if (AuthorChanged != null)
{
  //в другом потоке отписываемся, AuthorChanged = null 
  AuthorChanged(this, EventArgs.Empty); // NullReferenceException
}


Щастья вам в изучении матчасти.
Re[2]: Привязка данных в Windows Forms
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 30.01.09 07:34
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Доброго дня вам!


И вам!

S>По ходу у меня становится традицией отписываться на статьи...


S>В нарушение традициии эта приятно порадовала — умеют же если захотят. Как всегда — пустые придирки к коду. Ничего серьёзного — это ж сампл, не продакшн. Не обращяйте внимания и пишите ещё


Спасибо за отзыв, будем писать еще!

S>1) Мелочь:

S>
S>public event EventHandler<EventArgs> AuthorChanged;
S>

S>Зачем здесь генерик-версия? Кстати, правило хорошего тона — заодно реализовать INotifyPropertyChanged.

По поводу generic-версии, не знаю ... как-то само собой получилось!
По поводу INotifyPropertyChanged. Этим примером я хотел показать двойственность привязки данных. Т.е. для того, чтобы работала двусторонняя привязка нужно реализовать события PropertyNameChanged или реализовать интерфейс INotifyPropertyChanged. Здесь вначале я выполняю только один из шагов, потом реализую и другой вариант, с реализацией интерфейса INotifyPropertyChanged.

S>2) Совсем пустая придирка:

S>
S>if (AuthorChanged != null)
S>  AuthorChanged(this, EventArgs.Empty);
S>

S>Выносится в отдельный метод. Да, проверка на нулл может не сработать при многопоточности. Перед проверкой кэшируйте в локальной переменной.

Вы правильно заметили, что это не продакш код, поэтому отдельный метод только затруднит понимание кода. Опять же в контексте Windows Forms иногда точно известно, что подписка к событию и отписка от него происходит в потоке GUI, поэтому иногда такая проверка является излишней даже в продакш коде.

S>4) И ещё:

S>
S>public CustomBinder(Control control, string controlPropertyName,
S>                 object dataSource, string dataSourcePropertyName)
S>{
S>...
S>}
S>

S>Во-первых, поаккуратнее с исключениями в конструкторе — лучше Factory сделать. Во-вторых сначала стоит проверить на свойства сорс и таргет, и только потом подписываться на события. Опять, где отписка?И почему CustomBinder не IDisposable?

Опять же код не продакшен, а educational

S>5) А кто лайфтаймом биндингов управлять будет? Не, я понимаю, что оно будет жить вечно...

S>
S>  private void Bind()
S>  {
S>    CustomBinder authorPropertyManager = 
S>      new CustomBinder(authorTextBox, "Text", bookInfo, "Author");
S>    CustomBinder titlePropertyManager = 
S>      new CustomBinder(titleTextBox, "Text", bookInfo, "Title");
S>    CustomBinder isbnPropertyManager = 
S>      new CustomBinder(isbnTextBox, "Text", bookInfo, "ISBN");
S>    CustomBinder pageCountPropertyManager = 
S>      new CustomBinder(pageCountTextBox, "Text", bookInfo, "PageCount");
S>    CustomBinder publisherPropertyManager = 
S>      new CustomBinder(publisherTextBox, "Text", bookInfo, "Publisher");
S>  }
S>


Нет, вечно он жить не будет. Просто без студии, анализируя код статьи очень тяжело заметить управление временем жизни.
В конструкторе CusomBinder-а происходит следующий вызов:

if (dataSourcePropertyDescriptor.SupportsChangeEvents)
                dataSourcePropertyDescriptor.AddValueChanged(dataSource, DataSourcePropertyChanged);


Т.е. this подписывается на событие, ссылка на this осталась в цепочке делегатов dataSourcePropertyDescriptor-а. Т.о. время жизни CustomBinder-а определяется временем жизни propertyDescriptor-а, время жизни которого, соответственно, определяется временем жизни соответствующего контролла. Грохнется контрол, все остальные объекты станут не достижимы и попадут под сборку мусора.


S>Дальше есть ещё пара мелких косяков, наподобие непроверки IndexOf(...) на -1, если интересно — найдёте сами.


Спасибо, увидел!

S>Удачи!


И вам!
Re[2]: Привязка данных в Windows Forms
От: _FRED_ Черногория
Дата: 30.01.09 11:40
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Зачем здесь генерик-версия? Кстати, правило хорошего тона — заодно реализовать INotifyPropertyChanged.


"Заодно" неправильно, можно реализовать только один из подходов.

S>4) И ещё:


S>Во-первых, поаккуратнее с исключениями в конструкторе — лучше Factory сделать.

А что такого плохого в "исключениях в конструкторе", что замена на фабрику исправит?
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Привязка данных в Windows Forms
От: Sinix  
Дата: 31.01.09 09:28
Оценка:
Здравствуйте, SergeyT!

ST>Нет, вечно он жить не будет. Просто без студии, анализируя код статьи очень тяжело заметить управление временем жизни.

ST>В конструкторе CusomBinder-а происходит следующий вызов:

ST>
ST>if (dataSourcePropertyDescriptor.SupportsChangeEvents)
ST>                dataSourcePropertyDescriptor.AddValueChanged(dataSource, DataSourcePropertyChanged);
ST>


Если не отписываться, ссылка на подписчика живёт в эвент хандлере данных. Если данные живут дольше формы — вызываются обработчики событий на сдохшей форме с весьма вероятным эксепшном.

А код лучше сразу привыкать писать аккуратно, не переучишься...

2 _FRED_:
Насколько помню, МС Guidelines наоборот советуют реализовать и то и то. Прямые эвенты — для простых смертных, INotifyPropertyChanged — для биндинга. Ссылки не приведу — искать лень. Возможно и не прав...

Насчёт фабрик вместо конструктора — хз даже. Больше религия чем что либо ещё. В теории эксепшны низзя только ынутри статик конструкторов, что никак не затрагивает обычные... А, кажется дошло. Такой подход заставляет проверки делать до создания объекта, т.е. в теории кинуть эксепшн и оставить объект врассогласованном состоянии не получится. С другой стороны, даже если объект останется в рассогласованном указатель на него не ляжет в стек... Так что по-видимому просто религия
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.