Sabyasachi Mukherjee Ответов: 2

Привязка изменяющейся коллекции к combobox


Итак, вот в чем дело. В приложении WPF я заполняю BindableCollection (видеть: Калибурн.Микро[^]) из конструктора ViewModel.

Вот конструктор:

public UsersViewModel(IUsersUoW uow, IEventAggregator eventAggregator) : base(uow, eventAggregator)
{
    DisplayName = "Users";
    Users = new BindableCollection<User>(_uow.userrepo.FetchAll());
}


Короче говоря, _uow-это моя единица работы, а userrepo-мой репозиторий. Таким образом, это фактически заполняет свойство Users, которое, на мой взгляд, привязано к Combobox. Существует свойство SelectedUser, которое указывает на выбранный элемент ComboBox. Теперь в поле зрения находится множество текстовых полей, которые отображают различные свойства SelectedUser. Свойства можно редактировать, редактируя текст в текстовом поле.

Теперь, чтобы сохранить изменения, у меня есть такой метод:

public void Modify()
{
    var currentuser = _uow.userrepo.Find(SelectedUser.ID);
    currentuser.addr = Address;
    //save other properties
    _uow.userrepo.Update(currentuser);
    _uow.Complete();
    Status = "Modified!";
}


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

Метод обновления репозитория таков:

virtual public void Update(T updatedentity)
{
    _ctx.Set<T>().Attach(updatedentity);
    _ctx.Entry(updatedentity).State = EntityState.Modified;
}


Что я уже пробовал:

Одним из способов решения этой проблемы является повторное заполнение ComboBox после внесения изменений. Но мне кажется, что это клуджи.

Каков стандартный протокол, чтобы избежать устаревших данных, подобных этому? Должен ли я сделать пользователей недвижимости такими?

public BindableCollection<User> Users => new BindableCollection<User>(_uow.userrepo.FetchAll());


В этом случае, я думаю, будет удар по производительности, так как каждый раз, когда я обращаюсь к ComboBox, будет доступен репозиторий.

2 Ответов

Рейтинг:
2

RickZeeland

Это то, что я нашел о BindableCollection класс на:
SynchronizedObservableCollection и BindableCollection | атомная Блография[^]

Цитата:
чаще всего ему будет подаваться ObservableCollection
Так что, похоже, вам нужно использовать ObservableCollection.


Sabyasachi Mukherjee

BindableCollection наследует ObservableCollection под капотом. Я использовал BindableCollection, потому что я использую Caliburn.Микро.

RickZeeland

Возможно, вы можете выполнить следующие действия, описанные здесь: https://github.com/Caliburn-Micro/Caliburn.Микро/образцы дерева/мастер//установки/настройки.В WPF

Рейтинг:
12

J. Calhoun

Таким образом, проблема, которая, как я думаю, у вас есть, заключается в том, что вы изменяете запись в базе данных, но не обновляете запись в самой коллекции.

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

Кроме того, будьте осторожны с использованием

= new BindableCollection<User>(_uow.userrepo.FetchAll());
каждый раз, когда вы идете за покупками, потому что
new
может разорвать вашу связь. Я всегда стараюсь инициализировать коллекции, привязанные к представлению только один раз в конструкторе.

Кроме того, мне нравится BindableList, потому что вы можете отключить raise events do work, вернуться к событиям и сбросить привязки. Я нахожу, что он хорошо работает и с большими наборами данных.

Надеюсь, это поможет!


Sabyasachi Mukherjee

Спасибо, я только что превратил свою коллекцию в вычисляемое свойство, и вызов функции NotifyPropertyChanged() для коллекции всякий раз, когда она меняется, отлично справляется с этой задачей.