#c# #winforms #entity-framework #bindingsource #bindingnavigator
#c# #winforms #entity-framework #источник привязки #привязканавигатора
Вопрос:
У меня есть навигатор привязки с источником привязки в форме winforms. Мой источник данных поступает из списка entity framework.
Я хочу отслеживать состояние каждого объекта в моем источнике привязки, используя метод, которому я научился на курсе Джули Лерман в Pluralsight
Добавление и редактирование достаточно просты, я просто заполнил события кнопки добавления и удаления
private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e)
{
((IEntity)(this.personBindingSource.Current)).State = EntityState.Added;
}
private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e)
{
((IEntity)(this.personBindingSource.Current)).State = EntityState.Deleted;
}
Однако события EditItemClick нет, как я могу отследить, был ли изменен объект?
Обратите внимание, что я привязываюсь к отключенному списку доменного класса Person
List<Person> people = MyRepository.GetPeople();
this.personBindingSource.DataSource =people;
this.personBindingNavigator.BindingSource = this.personBindingSource;
У меня есть идентификатор интерфейса
public interface IEntity
{
EntityState State { get; set; }
}
public enum EntityState
{
Unchanged,
Added,
Modified,
Deleted
}
и Person наследует от этого
[Обновить]
просматривая свойства события BindingSource, я вижу, что CurrentItemChanged вызывается при изменении свойства. Однако оно также возникает при изменении самого текущего элемента.
Есть ли способ выяснить, по какой причине это было вызвано?
Комментарии:
1. Как вы привязываете значения данных к элементам управления в вашем навигаторе привязки? Если вы привязываете свойства объекта к элементам управления, то простое изменение значений через пользовательский интерфейс должно автоматически установить
EntityState.Modified
. Средство отслеживания сущностей должно обработать это за вас, если вы правильно привязываете.2. Спасибо @DavidTansey, я обновил вопрос, чтобы показать, что объекты отключены.
Ответ №1:
Поскольку ваши объекты отключены, отслеживание изменений в контексте недоступно, поэтому вам нужно отслеживать изменения самостоятельно.
Если вы измените свой метод репозитория для создания клонов извлекаемых пользователей, мы сможем повторно подключить исходные объекты в момент сохранения.
List<Person> originalPeople;
List<Person> modifiablePeople = MyRepository.GetPeople(out originalPeople);
Вы можете прочитать раздел
Создание клонированного объекта, содержащего текущие, исходные значения или значения базы данных, чтобы узнать, как создать клон ваших исходных объектов people.
MyRepository.SavePeople примет два аргумента: originalPeople (клоны) и modifiablePeople (измененные пользователи, привязанные к пользовательскому интерфейсу, содержащему изменения). Затем вы должны повторно подключить свой originalPeople в неизмененном состоянии, а затем применить изменения свойств от измененного пользователя итеративным способом:
var entry = context.Entry(original Person);
entry.CurrentValues.SetValues(modifiedPerson);
Прочитайте раздел о:
Установка текущих или исходных значений из другого объекта
Комментарии:
1. Спасибо @user978139, я думаю, должен быть способ помечать изменение по мере его возникновения …. может быть, что-то связано с INotifyChangeProperty
2. INotifyPropertyChanged полезен при обстоятельствах привязки, чтобы уведомлять элементы управления пользовательского интерфейса об обновлениях значений. Вы могли бы сохранить словарь пары строка / логическое значение ключ-значение свойств, которые были изменены для каждого объекта, к которому репозиторий имеет доступ. В репозитории вы бы повторили словарь и установили свойство как измененный контекст. Запись (блог). Свойство («Имя»). IsModified = true;
3. Это не отвечает на мой вопрос. Как я узнаю, что связанный объект был изменен?
Ответ №2:
private void bindingSource_ListChanged(object sender, ListChangedEventArgs e)
{
if (e.ListChangedType == ListChangedType.ItemChanged)
{
var entity = (IEntity)((BindingSource)sender).Current;
if (entity.State == EntityState.Unchanged)
{
entity.State = EntityState.Modified;
}
}
}