Знай, какая коллекция содержит меня! - PullRequest
1 голос
/ 12 мая 2011

в моем проекте 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 прослушивать событие NameChanged IMyClass и отменить изменение имени в случае необходимости. Но это не будет работать с упомянутым механизмом исключения и проверки Silverlight.

Есть идеи, как решить эту проблему?

Заранее спасибо,
Frank

Ответы [ 3 ]

0 голосов
/ 12 мая 2011

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

Если это сильные родительские / дочерние отношения, то во что бы то ни стало добавьте родительское свойство, но вы должны применить его - то есть вы не можете случайно добавить объект, который уже является дочерним для другого Коллекция, и добавив ее следует установить родительский.

Вы также должны убедиться, что существует только один API-интерфейс Add, т.е. вы вызываете метод для объекта? или в коллекции? любой из них работает, но наличие одного метода избавит от путаницы. Для этого почти наверняка понадобится пользовательская коллекция, чтобы избежать реализации Add по умолчанию.

0 голосов
/ 12 мая 2011

Вам не нужно свойство Parent в интерфейсе, просто элемент данных в реализующем классе. Передайте родительский элемент конструктору.

0 голосов
/ 12 мая 2011

Вы возлагаете на IMyClass неправильную ответственность. Он не знает о коллекции и не должен.

Ответственность за добавление объектов, отличающихся по имени, лежит на классе коллекции.

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

EDIT

Не возвращать собственность. Это не ответственность коллекции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...