我已大大简化了这一点,但我对这个解决这个问题的最佳方法有疑问。
在附带的屏幕截图中,我要求只能有一个主要联系人。用户应该能够从列表视图(屏幕截图的左侧)或详细视图(屏幕截图的右侧)更改主要联系人。
换句话说,如果用户要在列表视图中检查Jane Doe,则会取消选中John Smith旁边的复选框。在详细信息视图中也会出现相同的情况,如果选中Jane Doe的复选框,则会取消选择John Smith。
我正在使用Caliburn.Micro作为我的MVVM框架,并附加了示例项目。
我试图让项目变得非常简单。我没有解决附加项目中的问题,我希望对如何解决它有不同的想法。
由于
答案 0 :(得分:1)
业务对象有责任确定如果其他项成为主要项目会发生什么,因此您需要某种管理IsPrimary
标志的对象。
但是你这样做(自定义容器类型,中介等)你需要一些东西来调解变化
e.g。
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;
}
}
}
可能有更好的方法,例如拥有一个容器集合(它可以自己挂起属性等等......还要注意事件处理程序!)
您可以编写一个更通用的模板化版本来激发重载(因此您可以轻松地创建不同的调解器等子类)
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
}
答案 1 :(得分:0)
正如我所看到的,有几个基本选项。我要去的方向是创建一个名为Person的Model对象,并有一个名为IsPrimary的布尔属性。我希望这个模型对象实现INotifyPropertyChanged。在我的ViewModel对象中,我将拥有Person对象的BindingList集合对象。然后为复选框连接一些命令以触发Person对象中的更改,并且应该这样做。