知道哪个合集里有我!

发布于 2024-11-06 21:46:56 字数 1456 浏览 1 评论 0原文

在我的 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 属性的设置器,例如:

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 异常和验证机制。

有什么想法如何解决这个问题吗?

预先感谢,
坦率

in my Silverlight 4 project, I have a simple class implementing the interface like:

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

a parent class contains a collection of IMyClass elements like:

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

Now I want to make sure, that IMyClass.Name is unique in the Children collection. The user can change the IMyClass.Name - so I need to validate if the name is already in the collection. I want to use the Silverlight exception and validation mechanism, my XAML-textbox looks like:

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

So I need to check in the setter of the Name property like:

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");
    }
}

And here comes the problem: CollectionAlreadyContainsName needs to know the collection, but in an IMyClass-object I do not know in which collection I am. I would need to keep a reference to the parent like

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

which tastes bad to me because of cross referencing and the need to asure that the parent is always set properly. So I look for another way to do this. One idea was to let the ParentClass listen to a NameChanged-event of IMyClass and reverting the name change if necessary. But this would not work with the mentioned Silverlight exception and validation mechanism.

Any ideas how to address this?

Thanks in advance,
Frank

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半步萧音过轻尘 2024-11-13 21:46:56

您赋予 IMyClass 错误的责任。它不知道该集合,也不应该知道。

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

因此,重写/创建一个 add 方法来执行此操作,并使名称只读或订阅集合中名称的更改并在那里抛出错误。

编辑

不要恢复该属性。这不是收藏的责任。

You are giving the IMyClass the wrong responsibility. It doesn't know about the collection and it shouldn't.

It is the responsibility of the collection class to only add objects that differ in name.

So override/create an add method that does this and either make the name readonly or subscribe to the change of the name in the collection and throw an error there.

EDIT

Do not revert the property. That is not the responsibility of the collection.

情深如许 2024-11-13 21:46:56

这里的问题是事情没那么简单;一个对象可以被零个、一个或很多集合引用。假设孩子有充分的面向对象的理由了解父母(这实际上很少见),那么您需要决定需要支持哪一个。我不会在这里使用事件,因为事件也是多播的,可能会造成混乱。

如果它是强父/子关系,那么一定要添加父属性,但您应该强制执行它 - 即您不能意外添加已经是另一个集合的子对象的对象,并添加它应该设置父级。

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

The problem here is that it isn't that simple; an object can be referenced by zero, one or many, many collections. Assuming that there is a good OO reason for the child to know about the parent (which is actually pretty rare), you need to decide which it is you need to support. I wouldn't use events here as events are also multicast, potentially confusing things.

If it is a strong parent/child relationship, then by all means add a parent property, but you should enforce it - i.e. you can't accidentally add an object that is already a child of another collection, and adding it should set the parent.

You should also ensure that there is only one Add api - i.e. do you call a method on the object? or on the collection? either works, but having one method will save confusion. You will almost certainly need a custom collection to do this, to avoid the default Add implementation.

拒绝两难 2024-11-13 21:46:56

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

You don't need a Parent property in the interface, just a data member in the implementing class. Pass the parent to the constructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文