2015-01-11 4 views
0

У меня есть класс, содержащий много свойств. Один из них нуждается в специальном пользовательском интерфейсе для редактирования. Пользователь может нажать править для этого свойства в пользовательском интерфейсе, затем внести изменения и либо нажать OK, либо ОтменитьЭффективный способ обновления внешней структуры данных UI

например.

class A{ 
    private List<Employee> employees; 

    public void EditMyEmployees(){ 
     EmployeeEditorForm editor = new EmployeeEditor(employees); 
     if(editor.ShowDialog() == DialogResult.OK){ 
      employees = editor.GetEditedEmployeesList(); 
     } 
    } 
} 

Проблема в предыдущем коде, что редактор имеет копию ссылки на список сотрудников

и когда редактор делает любые изменения в списке это будет отражено в исходном объекте. Так, нажав ОК или Отмена будет иметь тот же эффект (объект уже обновлен) и нет необходимости в стадии

employees = editor.GetEditedEmployeesList(); 

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

Я ищу шаблон дизайна, который может сделать это лучше.

+1

Вы можете использовать шаблон команды. Ваш редактор не будет напрямую обновлять список сотрудников, он будет создавать команды, которые могут применяться для изменения списка. Если пользователь нажал «ОК», команды будут применены, если не будут проигнорированы. – dbugger

ответ

1

Вам не обязательно полностью копировать всю коллекцию. Вам просто нужно отслеживать измененные элементы. В вашей EmployeeEditor используйте три списка (List<Employee> отслеживать:

  1. Добавлена ​​сотрудников
  2. Удалены сотрудников
  3. Changed сотрудников

После отмены, вам нужно будет удалить "добавил" пунктов, добавьте обратно «удаленные» предметы и замените измененные предметы на их исходное состояние.

Обратите внимание, что список замененных сотрудников будет чтобы сохранить копию исходного состояния объекта. Если класс Employee имеет уникальный идентификатор, вы можете сопоставить его с идентификатором. В противном случае «измененный» список должен быть List<Tuple<Employee, Employee>>, чтобы вы могли хранить соответствующие элементы.

Также обратите внимание, что при внесении изменений в список сотрудников вам также необходимо внести необходимые изменения в эти три списка. Например, если новый сотрудник добавлен и затем удален, вам также необходимо удалить эту запись из «добавленного» списка. Или можно изменить сотрудника, а затем удалить, и в этом случае вам также нужно удалить из «измененного» списка.

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

1

Здесь есть два вида изменений: (1) изменения в списке (добавление/удаление) и (2) изменение отдельных элементов списка (в этом случае сотрудники).

Теперь часть проблемы исходит из семантики ОК/Отмена. Если вы ограничите область этих двух кнопок изменениями второго типа (т. Е. Измените элементы списка), вы сможете обрабатывать Удалить с помощью диалогового окна подтверждения этого конкретного действия («Удалить такое-то»?). Для дополнения вам ничего не нужно, просто добавьте новый элемент в список.Если пользователь изменит свое мнение, они все равно будут иметь действие «Удалить».

Для изменений в конкретном элементе (второй вид) вы можете использовать шаблон команды, как указано в комментарии. Более просто, вы можете инициализировать временные переменные для всех полей, отображаемых вашим редактором из элемента под редакцией. Когда пользователь изменяет некоторые значения, ваш редактор будет обновлять соответствующие временные файлы. Если пользователь нажмет «Отмена», вы просто забудете эти изменения (или повторно инициализируйте их из элемента). Если пользователь нажимает «Применить» (да, вы должны также включить кнопку «Применить»), вы теперь будете записывать каждое из временных значений в атрибут соответствующего элемента. Если пользователь нажимает «ОК», вы будете применять и закрывать.

Смежные вопросы