知道哪个系列包含我!

时间:2011-05-12 10:10:52

标签: c# silverlight validation binding

在我的Silverlight 4项目中,我有一个实现界面的简单类,如:

public interface IMyClass
{
  string Name { get; set; }
  anyotherclass Value { get; set; }
}

父类包含一系列IMyClass元素,如:

public class ParentClass
{
  ObservableCollection<IMyClass> Children { get; }
}

现在我想确保,IMyClass.Name在Children集合中是唯一的。用户可以更改IMyClass.Name - 所以我需要验证名称是否已经在集合中。我想使用Silverlight异常和验证机制,我的XAML文本框看起来像:

<TextBox Text="{Binding 
                ValidatesOnExceptions=true,
                NotifyOnValidationError=true,
                Mode=TwoWay,
                Path=Name}"/>

所以我需要检查Name属性的setter,如:

public string Name
{
    get { return _name; }
    set 
    {
        if (value == _name)
            return;

        if (CollectionAlreadyContainsName(this, value))
            throw new ArgumentException("The name already exists");
        else
            _name = value;

        OnPropertyChanged("Name");
    }
}

问题出现了:CollectionAlreadyContainsName需要知道集合,但在IMyClass对象中,我不知道我在哪个集合中。我需要保持对父母的引用,如

public interface IMyClass
{
  string Name { get; set; }
  anyotherclass Value { get; set; }
  ParentClass Parent { get; }
}

由于交叉引用而对我不好,并且需要确保父项始终设置正确。所以我寻找另一种方法来做到这一点。一个想法是让ParentClass监听IMyClass的NameChanged事件,并在必要时恢复名称更改。但是这不适用于提到的Silverlight异常和验证机制。

任何想法如何解决这个问题?

提前致谢,
弗兰克

3 个答案:

答案 0 :(得分:0)

你给了IMyClass错误的责任。它不知道该集合,它不应该。

集合类的职责是仅添加名称不同的对象。

因此,覆盖/创建一个执行此操作的add方法,并使该名称为readonly或订阅集合中名称的更改,并在那里抛出错误。

修改

不要还原该属性。这不是该系列的责任。

答案 1 :(得分:0)

这里的问题是它并不那么简单;一个对象可以由零个,一个或多个多个集合引用。假设有一个很好的OO理由让孩子知道父母(实际上非​​常罕见),你需要决定你需要支持哪一个。我不会在这里使用事件,因为事件多播,可能会让人感到困惑。

如果它是一个强大的父/子关系,那么无论如何添加一个父属性,但你应该强制执行它 - 即你不能不小心添加一个已经是孩子的对象另一个集合,并添加它应该设置父。

您还应确保只有一个Add api - 即您是否在对象上调用方法?还是收藏品?要么有效,要么有一种方法可以避免混淆。您几乎肯定需要一个自定义集合来执行此操作,以避免默认的Add实现。

答案 2 :(得分:0)

接口中不需要Parent属性,只是实现类中的数据成员。将父项传递给构造函数。