0

截屏

我已经大大简化了这一点,但是我对解决这个问题的最佳方法有疑问。

在随附的屏幕截图中,我要求只能有一个主要联系人。用户应该能够从列表视图(屏幕截图的左侧)或详细信息视图(屏幕截图的右侧)更改主要联系人。

换句话说,如果用户在列表视图中选中 Jane Doe,John Smith 旁边的复选框将被取消选中。在 Detail 视图中也会发生同样的情况,如果选中 Jane Doe 的复选框,则会取消选中 John Smith。

我将 Caliburn.Micro 用于我的 MVVM 框架,并附上了示例项目。

我试图让项目变得非常简单。我没有解决附件项目中的问题,我希望对如何解决它有不同的想法。

WpfApplication1.zip

谢谢

4

2 回答 2

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
}
于 2013-01-07T13:51:51.237 回答
0

在我看来,有几个基本选项。我的方向是创建一个名为 Person 的 Model 对象,并拥有一个名为 IsPrimary 的布尔属性。我会让这个模型对象实现 INotifyPropertyChanged。在我的 ViewModel 对象中,我将有一个 Person 对象的 BindingList 集合对象。然后为复选框连接一些命令以触发 Person 对象中的更改,这应该可以做到。

于 2013-01-07T02:10:38.463 回答