Binding
От: Аноним  
Дата: 17.10.10 15:38
Оценка: 9 (1)
Привет всем.

Делаю привязку данным.
Одни и тот же пользовательский элемент с контролами используется
для отображение свойств различных объектов. Для этого меняется
у этого элемента DataContex
Все вроде работает, заметил что элементы имеющие Binding.UpdateSourceTrigger=LostFocus
(это например все TexBox и пр)
не запоминаются если не убрать с него фокус (собственно, так и было задумано).
Что я должен сделать, прежде чем изменить DataContex, пробегать по всему дереву
выявляя привязки и вызывать UpdateSource() мне как то совсем не хочется,
можно конечно поменять Binding.UpdateSourceTrigger=PropertyChanged, но это
тоже не совсем правильно.
Так какой стандартный подход?

18.10.10 06:24: Перенесено из '.NET'
Re: Binding
От: MxMsk Португалия  
Дата: 17.10.10 16:42
Оценка: 9 (1)
Здравствуйте, Аноним, Вы писали:

А>Что я должен сделать, прежде чем изменить DataContex, пробегать по всему дереву

А>выявляя привязки и вызывать UpdateSource() мне как то совсем не хочется
Есть Keyboard.FocusedElement
Re[2]: Binding
От: Аноним  
Дата: 18.10.10 05:04
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Здравствуйте, Аноним, Вы писали:


MM>Есть Keyboard.FocusedElement


Хорошо, это решение меня устроит. Есть еще проблема связанная с DataGrid
Суть ее в том, что если пользователь не ушел с редактируемой строки
(т.е. не отработали события связанные с концом редактирования строки)
при попытке повторно установить данный DataContext, возникает исключение
"DeferRefresh" не разрешено во время выполнения операции AddNew или EditItem.
('Defer Refresh' is not allowed during an AddNew or Edit Item transaction.)
Кто-нибудь понимает, где она хранит информацию, что исключение выбрасывается не при смене
редактируемой коллекции на др., а при возврате DataContext с коллекцией которая ранее
редактировалась. И как поступать с пользовательским интерфейсом, что нужно сделать,
чтобы избежать подобной ситуации?
Re[3]: Binding
От: MxMsk Португалия  
Дата: 18.10.10 06:48
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Хорошо, это решение меня устроит. Есть еще проблема связанная с DataGrid

А>Суть ее в том, что если пользователь не ушел с редактируемой строки
А>(т.е. не отработали события связанные с концом редактирования строки)
А>при попытке повторно установить данный DataContext, возникает исключение
А>"DeferRefresh" не разрешено во время выполнения операции AddNew или EditItem.
А>('Defer Refresh' is not allowed during an AddNew or Edit Item transaction.)
А>Кто-нибудь понимает, где она хранит информацию, что исключение выбрасывается не при смене
А>редактируемой коллекции на др., а при возврате DataContext с коллекцией которая ранее
А>редактировалась. И как поступать с пользовательским интерфейсом, что нужно сделать,
А>чтобы избежать подобной ситуации?

Ну так у самого DataGrid есть методы CommitEdit и CancelEdit. Правда я не знаток этого контрола, но и MSDN никто не отменял.

Есть еще такой интерфейс — IEditableCollectionView. Мне кажется лучше решить проблему через него. Этот интерфейс поддерживается как объектом, лежащем в свойстве DataGrid.Items, так и представлением ListCollectionView.

Еще раз оговорюсь, что я с таким пока не сталкивался и описываю первое попавшееся решение. Чую, что всё может быть гораздо проще, может кто и напишет
Re[4]: Binding
От: Аноним  
Дата: 18.10.10 11:37
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Ну так у самого DataGrid есть методы CommitEdit и CancelEdit. Правда я не знаток этого контрола, но и MSDN никто не отменял.


MM>Есть еще такой интерфейс — IEditableCollectionView. Мне кажется лучше решить проблему через него. Этот интерфейс поддерживается как объектом, лежащем в свойстве DataGrid.Items, так и представлением ListCollectionView.


оговорюсь сразу DataGrid.CommitEdit() — не помогает, помогает IEditableCollectionView.CommitNew(),CommitEdit().

Вся прелесть связывания (Binding) с моей точки зрения в скрытие информации по редактированию, я не знаю как будет редактироваться данный объект класса (в каких пользовательских элементах) и знать не хочу (ведь его законы редактирования могут поменяться) Т.е. есть некий FrameworkElement (взаимодействующий с пользователем), у него есть DataContext от нас требуется только его инициализировать и пользователь что-то там может поменять. Заметьте, что в качестве DataContext может выступать (например) SelectedItem некого др. элемента управления и при перемещении по строчкам, часть введенных данных с точки зрения пользователя не сохраняется из-за Binding.UpdateSourceTrigger=LostFocus, а часть вызывает исключения из-за IEditableCollectionView, причем в общем случае коммитить все подряд нельзя, иначе это приводит к появлению пустых фантомов в коллекциях (т.е. пользователь в DataGrid перешел в режим редактирования и ничего не ввел, вообще это нужно откатить) если мы выполним IEditableCollectionView.CommitNew() получим в коллекции совершенно пустую строку (ну или некую ошибку, если ее ввод не возможен) Раньше эта ситуация разруливалась на уровне элемента DataGrid сейчас в WPF, учитывая что одна строка DataGrid может содержать все что угодно, проблема вставки пустой строки в общем виде не решается вовсе. Странно что нет события BeforeDataContextChanged — т.е. чтобы при старом контексте можно было бы что-нибудь успеть сохранить. Это все мысли вслух. Просто такая интересная идея, на практике оказывается не такой уж и интересной, хотя возможно я просто не умею ее правильно готовить ...
Re: Binding
От: Mr.Delphist  
Дата: 22.10.10 10:14
Оценка:
Не знаю, подойдет ли в твоём случае, но меня выручил такой вот "manual refresh", нагугленный в каком-то зарубежном блоге:

            BindingExpression binding = myTextBox.GetBindingExpression(TextBox.TextProperty);
            if (null != binding)
            {
                binding.UpdateSource();
            }


Соответственно, вместо myTextBox может быть всяко разно контролы (тогда вместо TextBox надо подставлять соответствующий тип)
Re[2]: Binding
От: Аноним  
Дата: 22.10.10 12:45
Оценка:
MD>
MD>            BindingExpression binding = myTextBox.GetBindingExpression(TextBox.TextProperty);
MD>            if (null != binding)
MD>            {
MD>                binding.UpdateSource();
MD>            }
MD>

Да это все правильно и все понятно, писал то я совсем о другом.
1. Я должен "знать" в соответствующем коде, что элемент содержит myTextBox, а этого как раз и хотелось бы избежать. Ведь завтра захочется изменить эту форму и myTextBox будет заменен чем то еще, а редактировать придется по всему проекту
2. Нет стандартного механизма сохранения недосохраненного содержимого формы редактирования при смене контекста (DataContext)
3. Подобная практика работы (которую ты привел) приводит к появлению пустых записей в различных редактируемых коллекции, и что есть пустая запись, как правило понять в общем виде очень сложно.
я думал, кто-то опровергнет, и расскажет как правильно работать, но все что-то молчат
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.