2013-01-06 3 views
0

ScreenshotВзаимно Эксклюзивная недвижимость через предметы в коллекции

я упростил это значительно, однако у меня есть вопрос, как к этому наилучшим образом решить эту проблему.

На прилагаемом скриншоте у меня есть требование, чтобы был только один первичный контакт. Пользователь должен иметь возможность изменять Первичный контакт либо из вида списка (в левой части экрана), либо в виде детализации (в правой части экрана).

Другими словами, если пользователь должен был проверить Jane Doe в представлении списка, флажок рядом с Джоном Смитом будет отменен. То же самое произойдет в представлении «Детали», если будет установлен флажок для Jane Doe, John Smith будет отменен.

Я использую Caliburn.Micro для моей структуры MVVM и приложил образец проекта.

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

WpfApplication1.zip

Благодаря

ответ

1

Обязанности бизнес-объектов определять, что происходит с другими элементами, если вы станете первичными, поэтому вам нужен какой-то объект, который управляет флагом IsPrimary.

Однако вы это делаете (пользовательский тип контейнера, посредник и т.д.) вам нужно что-то опосредует изменения

например

public class Mediator 
{ 
    IList<Contact> _contacts = null; 

    public Mediator(IList<Contact> contacts) 
    { 
     _contacts = contacts; 

     foreach(var c in contacts) 
     { 
      c.PropertyChanged += ContactPropertyChanged; 
     } 
    } 

    private bool _isChanging = false; 

    private void ContactPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     var current = sender as Contact; 

     if(e.PropertyName == "IsPrimary" && !_isChanging && current.IsPrimary) 
     { 
      _isChanging = true; 

      foreach(var c in _contacts.Where(x => x != current) 
      { 
       c.IsPrimary = false; 
      } 

      _isChanging = false; 
     } 
    } 
} 

Есть, вероятно, более эффективные способы, как иметь коллекцию контейнера (который перехватывает PropertyChanged и т.д. по себе ... также следить за обработчик событий!)

Вы могли бы написать более общие шаблонные версия, которая вызывает перегрузку (так что вы можете легко просто подклассы создавать разные медиаторы и т. д.)

public class Mediator<T> 
{ 
    IList<T> _items = null; 

    public Mediator(IList<T> items, params string[] watchedProperties) { ... etc 

    protected virtual OnWatchedPropertyChanged(T sender, string PropertyName) 
    { 
    } 
} 

public ContactMediator : Mediator<Contact> 
{ 
    public ContactMediator(IList<Contact> contacts, params string[] watchedProperties) { ... 

    override OnWatchedPropertyChanged(Contact object, string propertyName) { ... etc 
} 
+0

В моем реальном приложении у меня уже был класс коллекций (т. Е. ContractCollection), который управлял этим требованием. Однако я выбрал очень сложный подход :). Мне нравится этот подход намного лучше. Спасибо за помощь! –

0

Как я вижу, есть несколько основных вариантов. Направление, на которое я хотел бы пойти, было бы создать объект Model под названием Person и иметь логическое свойство, называемое IsPrimary. Я бы использовал этот объект модели INotifyPropertyChanged. В моем объекте ViewModel у меня будет объект коллекции BindingList объектов Person. Затем подключите некоторые команды для флажков, чтобы инициировать изменения в объекте Person, и это должно сделать это.

+0

Уверен, у меня это уже есть в решении, которое я приложил к исходному вопросу. Усложнение заключается в том, что существует только один первичный контакт. –

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