Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Биндинги / 12 сообщений из 12, страница 1 из 1
28.12.2010, 12:42
    #37038784
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
Здравствуйте.

У меня не работает обновление данных из собственно данных в контрол. Для того, чтобы данные обновлялись советуют использовать INotifyCollectionChanged, INotifyPropertyChanged или ObservableCollection, который уже их реализует.
Использую ObservableCollection, обновления данных нет, но сам биндинг как бы работает.

Прилагаю тестовый проект.
Меняя #define в ViewModel можно подгружать данные синхронно, либо асинхронно.
В первом случае биндинг подгружает данные, потому что они доступны сразу.
Во втором случае он тоже подгружает данные, но на момент привязки данные пустые. А когда данные обновляются, изменения не отражаются в контроле.
...
Рейтинг: 0 / 0
28.12.2010, 13:35
    #37038931
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
enigmatic,

ObservableCollection реализует INotifyCollectionChanged для изменений в самой коллекции, и ничего не знает о ViewModel.Model.

Тут два пути:

1) в конструкторе создавать пустую ObservableCollection (Model = new ItemList();) и в обработчике service_DataLoaded запихивать туда элементы (foreach (var item in e.list) Model.Add(item);) - тогда отработает нотификация ObservableCollection

2) реализовать INotifyPropertyChanged для ViewModel, и в обработчике service_DataLoaded извещать об изменении свойства Model (this.Model = e.list; OnPropertyChanged("Model");)

вероятно 2) предпочтительней (мало ли для каких еще свойств понадобится нотифицировать об изменениях)
...
Рейтинг: 0 / 0
28.12.2010, 13:39
    #37038944
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
LRвероятно 2) предпочтительней (мало ли для каких еще свойств понадобится нотифицировать об изменениях)
Вряд ли. Как говорят, нужен велосипед, - а предлагают танк. "Ну мало ли - стрелять ещё придётся..."
...
Рейтинг: 0 / 0
28.12.2010, 13:44
    #37038962
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
МСУВряд ли.
в 1) случае перегонять из одной коллекции в другую - уже некрасиво, да и нотификаций будет столько же сколько элементов - против одной во 2-м случае - неэффективно...
...
Рейтинг: 0 / 0
28.12.2010, 14:17
    #37039044
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
LR, ну "перегонять" я обычно автоматизирую с помощью экстеншена:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
public static T ObjectCopy<T>(this T source)
{
    if (Object.ReferenceEquals(source, null))
    {
        return default(T);
    }

    XmlSerializer serializer = new XmlSerializer(source.GetType());
    using (Stream stream = new MemoryStream())
    {
        serializer.Serialize(stream, source);
        stream.Seek(0, SeekOrigin.Begin);
        return (T)serializer.Deserialize(stream);
    }
}

Итого, получаем компакный набор букаф в одну строчку:

Код: plaintext
Model.Items = Model.ItemsBuffer.ObjectCopy<ObservableCollection<Category>>();
...
Рейтинг: 0 / 0
28.12.2010, 15:44
    #37039256
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
LRenigmatic,

ObservableCollection реализует INotifyCollectionChanged для изменений в самой коллекции, и ничего не знает о ViewModel.Model.

Тут два пути:

1) в конструкторе создавать пустую ObservableCollection (Model = new ItemList();) и в обработчике service_DataLoaded запихивать туда элементы (foreach (var item in e.list) Model.Add(item);) - тогда отработает нотификация ObservableCollection

2) реализовать INotifyPropertyChanged для ViewModel, и в обработчике service_DataLoaded извещать об изменении свойства Model (this.Model = e.list; OnPropertyChanged("Model");)

вероятно 2) предпочтительней (мало ли для каких еще свойств понадобится нотифицировать об изменениях)
2-й вариант то, что нужно, т.к. модель будет меняться целиком, а не будут добавляться/удаляться итемы из нее. Думал, как это сделать с помощью INotifyCollectionChanged для ItemList. А INotifyPropertyChanged для ViewModel как раз то, что нужно.
Действительно работает.
Но почему оно работает?
Почему мы вызываем OnPropertyChanged в service_DataLoaded?
Почему не в сеттере модели, как это делается в примерах по INotifyPropertyChanged:
Код: plaintext
1.
2.
3.
4.
5.
6.
        public ItemList Model {
            get { return this.Model; }
            set {
                this.Model = value;
                OnPropertyChanged();
            }
        }
Да оно улетит в бесконечный цикл. Но почему оно работает?
Я полный нуб, да.
Заранее благодарю.
...
Рейтинг: 0 / 0
28.12.2010, 15:58
    #37039297
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
enigmaticПочему мы вызываем OnPropertyChanged в service_DataLoaded?
Почему не в сеттере модели, как это делается в примерах по INotifyPropertyChanged:
ну конечно правильней в сеттере свойства, " и в обработчике service_DataLoaded извещать об изменении свойства Model " - это я для проверки так пробовал, в спешке и ляпнул...
о бесконечном цикле не понял...
...
Рейтинг: 0 / 0
28.12.2010, 15:59
    #37039299
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
enigmatic
Код: plaintext
1.
2.
3.
4.
5.
6.
        public ItemList Model {
            get { return this.Model; }
            set {
                this.Model = value;
                OnPropertyChanged();
            }
        }
Да оно улетит в бесконечный цикл. Но почему оно работает?

Извиняюсь, чушь написал.

enigmaticНо почему оно работает?

A change-notification handler notifies a binding target that a change has been
made. This enables a target to automatically respond to changes.
Все, понял. Оповещаем ведь цель привязки.
...
Рейтинг: 0 / 0
28.12.2010, 16:00
    #37039305
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
enigmatic
Код: plaintext
1.
2.
3.
4.
5.
6.
        public ItemList Model {
            get { return this.Model; }
            set {
                this.Model = value;
                OnPropertyChanged();
            }
        }

а, теперь понял про цикл )))) заведите переменную private ItemList _model
...
Рейтинг: 0 / 0
28.12.2010, 16:04
    #37039320
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
LRenigmaticПочему мы вызываем OnPropertyChanged в service_DataLoaded?
Почему не в сеттере модели, как это делается в примерах по INotifyPropertyChanged:
ну конечно правильней в сеттере свойства, " и в обработчике service_DataLoaded извещать об изменении свойства Model " - это я для проверки так пробовал, в спешке и ляпнул...
о бесконечном цикле не понял...
Значит с сеттером свойства все верно. Хорошо.

А бесконечный цикл там получается из-за того, что нет поля для свойства Model.
Вот оно и гоняет себя в цикле:
Код: plaintext
1.
2.
3.
public ItemList Model {
get { return this.Model; }
...
Тут я сам виноват.

LR,
спасибо за помощь!
...
Рейтинг: 0 / 0
28.12.2010, 18:36
    #37039688
i
i
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
enigmaticЗдравствуйте.

У меня не работает обновление данных из собственно данных в контрол. Для того, чтобы данные обновлялись советуют использовать INotifyCollectionChanged, INotifyPropertyChanged или ObservableCollection, который уже их реализует.
Использую ObservableCollection, обновления данных нет, но сам биндинг как бы работает.

Прилагаю тестовый проект.
Меняя #define в ViewModel можно подгружать данные синхронно, либо асинхронно.
В первом случае биндинг подгружает данные, потому что они доступны сразу.
Во втором случае он тоже подгружает данные, но на момент привязки данные пустые. А когда данные обновляются, изменения не отражаются в контроле.

В SL есть баг с утечкой для списка и DataGrid(радуйся, MCУ).
Работает такой вариант:
Если существующий список _list== null, то присваеваем ему значение полученного списка, иначе: осуществляем его очистку_list.Clear(); копируем элементы полученного списка в существующий( foreach(var item in value) _list.Add(item); )
...
Рейтинг: 0 / 0
30.12.2010, 10:38
    #37042133
enigmatic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Биндинги
iВ SL есть баг с утечкой для списка и DataGrid(радуйся, MCУ).
Работает такой вариант:
Если существующий список _list== null, то присваеваем ему значение полученного списка, иначе: осуществляем его очистку_list.Clear(); копируем элементы полученного списка в существующий( foreach(var item in value) _list.Add(item); )
Можно поподробнее про то как это устранить в данном случае и про эту конкретную утечку?
Гугл выдает по запросу "memory leak listbox silverlight", но только по скроллингу.
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Биндинги / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]