Могу ли я сделать так, чтобы редактор коллекции по умолчанию и/или пользовательский UIEditor вызывали метод доступа set для свойства?

Я пишу подключаемый модуль для приложения, в котором у меня есть собственный класс, который атрибутирует собственные объекты программы. API позволяет мне читать и записывать строки с ключами непосредственно в объекты в собственном файле и из них. Таким образом, вместо чтения и записи в закрытые поля в средствах доступа Get и Set каждого свойства я читаю и записываю эти пользовательские строки в собственные объекты в программе и из них.

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

Поэтому я настроил свойство с помощью XmlSerializer. Метод доступа GET считывает пользовательскую строку из собственных объектов, а затем строка десериализуется в экземпляр FloorCollection. Метод доступа SET делает обратное, считывая экземпляр FloorCollection и сериализуя его в пользовательскую строку.

Вот как выглядит моя собственность:

public FloorCollection Floors
{
    get 
    {
        string oldString = this.GetBaseObjUserString("CPFloors");
        if (oldString == null) return null;

        XmlSerializer serializer = new XmlSerializer(typeof(FloorCollection));
        StringReader strReader = new StringReader(oldString);

        FloorCollection newCollection =                 
        (FloorCollection)serializer.Deserialize(strReader);
        return newCollection;
    }

    set 
    {
        FloorCollection newCol = value;

        if (newCol == null) return;

        //serializes new collection
        XmlSerializer serializer = new XmlSerializer(typeof(FloorCollection));
        StringWriter sw = new StringWriter();

        serializer.Serialize(sw, newCol);

        string newString = sw.ToString();

        this.SetBaseObjUserString("CPFloors", newString);
    }
}

Я могу открыть это свойство коллекции через PropertGrid в редакторе коллекции по умолчанию. Однако редактор коллекции по умолчанию редактирует коллекцию только по ссылке, предоставленной методом доступа GET, а не вызывает метод доступа SET, чтобы сохранить ее обратно в объект. Таким образом, я могу редактировать коллекцию в редакторе по умолчанию, но когда я закрою и снова открою редактор, коллекция не изменится, потому что метод доступа SET никогда не вызывается для сериализации коллекции обратно в пользовательскую строку в собственном объекте.

Можно ли изменить редактор коллекции по умолчанию, чтобы он вызывал метод доступа set к свойству? Если я настрою пользовательский UITypeEditor для свойства, есть ли способ сохранить его обратно в свойство с помощью средства доступа к набору свойств? Или есть какой-то другой способ заставить код, который обращается к свойству коллекции, получить и установить свойство по значению, а не по ссылке?


person Eric Anastas    schedule 30.07.2009    source источник


Ответы (1)


Я не верю, что XML-сериализатор когда-либо вызовет метод доступа set для коллекции. Вместо этого он просто вызовет метод Add экземпляра коллекции, который он извлекает из метода доступа get.

Я считаю, что вам нужно, чтобы ваш тип коллекции переопределял методы Add и Remove и тому подобное, чтобы изменить коллекцию, а затем сериализовать измененную коллекцию обратно в свойство пользователя.

person John Saunders    schedule 30.07.2009
comment
Ху? Вы получили это задом наперёд. Метод доступа set — это место, где происходит сериализация, точно так же, как метод доступа get — место, где происходит десериализация. Проблема заключается в том, что когда я редактирую коллекцию через PropertyGrid с редактором коллекции по умолчанию или пользовательским редактором UITypeEditor, эталонная коллекция редактируется напрямую, а не передается обратно через мой доступ к SET, где он будет сериализовать новое значение. - person Eric Anastas; 31.07.2009
comment
Нет, у меня это реально. Поскольку метод доступа set никогда не будет вызываться, вам понадобится специальная коллекция, которая будет сериализоваться при каждом изменении коллекции. - person John Saunders; 31.07.2009
comment
Ну, коллекции действительно не нужно знать, чтобы сериализоваться, когда она изменяется. Скорее класс с коллекцией должен знать, когда коллекция изменяется, чтобы он мог ее повторно сериализовать. Моя пользовательская коллекция наследуется от BindingList‹Floor›, поэтому у нее есть событие listchanged, на которое я мог бы подписаться. - person Eric Anastas; 31.07.2009