Re: Связка нескольких контролов через DataContext
От: Vladek Россия Github
Дата: 23.04.11 17:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Рассмотрим следующие варианты использования

А>1) textbox + datagrid , вводим текст в textbox в гриде видим отфильрованную по некоторому запросу информацию
А>2) datagrid + datagrid , первый датагрид инициализируется по sql запросу при выборе элемента во второй датагрид загружается информация через запрос.

А>Предполагается что контролы ничего не знают друг о друге.

А>Есть некий контроллер который знает названия контролов и у него есть доступ к DataContext и информация о пути к данным через него.



А>Соответственно по п.3. находим 2 датаконтекста, берем объекты которые им назначены, получаем в результате 2 объекта не DependencyObject, для которых нет метода SetBinding, а хотелось бы использовать именно гибкость Bindingа , в том числе чтобы не изобретать велосипед для путей TargetPath, SourcePath, а использовать как принято в Bindings.




А>Как лучше организовать такие связи ?


Описанный вариант реализации никуда не годится — слишком сложный и запутанный. И это при том, что описанные два варианта использования тривиальны в реализации на WPF!

У нас есть объект, который устанавливается в качестве DataContext где-то на верхнем уровне: в Window или в UserControl. С помощью биндинга или в коде — не важно.

1) У объекта есть строковое свойство которое привязывается к TextBox с UpdateSourceTrigger=PropertyChanged. Объект при изменении этого свойства меняет фильтр у другого своего свойства типа ICollectionView (реализуемый с помощью ListCollectionView), которое привязано к DataGrid. Всё — сценарий реализован!

Схематично:
MyObject -> DataContext
string MyObject.Filter -> TextBox.Text
ICollectionView My.Object.Data (ObservableCollection<> -> ListCollectionView) -> DataGrid.ItemsSource

2) Данными по запросу заполняется коллекция ObservableCollection<>, она никуда не привязывается. Для привязки предназначена её обёртка типа ListCollectionView. У первого такого свойства мы подписываемся на событие CurrentChanged и в обработчике заполняем данными второе свойство, организованное подобным же образом. Оба свойства привязываются к DataGrid-ам, свойство DataGrid.IsSyncronizedWithCurrentItem ставим в true.

ICollectionView My.Object.Data1 (ObservableCollection<> data1 -> ListCollectionView dataView1) -> DataGrid.ItemsSource
ICollectionView My.Object.Data2 (ObservableCollection<> data2 -> ListCollectionView dataView2) -> DataGrid.ItemsSource
dataView1.CurrentChanged -> запрос данных для data2, параметр(ы) из dataView1.Current

И всё! Никто ни о ком ничего не знает, никаких ковыряний в контекстах данных, никаких костылей.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.