![]() |
Модераторы: Partizan, gambit |
![]() ![]() ![]() |
|
Тигер |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 4.4.2010 Репутация: нет Всего: нет |
Здравствуйте, такая задач: Нужно сохранить CollectionItems (или IEnumerate ItemsSource) чтобы потом, восстановить значения в TreeView.
Тоесть обычно для этого понадобилось бы клонировать объект коллекции, однако в C# нет нативных методов для клонирования, а значит разработчики C# считаю эту операцию костыльной. Следовательно для решения данной задачи должен быть более оптимальный способ. Спасибо! |
|||
|
||||
dzaraev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 12.1.2013 Репутация: нет Всего: 1 |
Во-первых нативные методы есть и клонирование - совсем не костыльная операция сама по себе.
Вот что есть из коробки (на вскидку): Object.MemberwiseClone - метод ICloneable - интерфейс А во-вторых - в чем проблема просто сохранить ссылку на значение ItemSource? --------------------
Если вопрос решён - помечайте тему. |
|||
|
||||
Тигер |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 4.4.2010 Репутация: нет Всего: нет |
Ну интерфейс - это же не нативная поддержка? MemberwiseClone() не реализован в коллекции итемов, или я просто не там искал.
Не совсем понял, а как я буду восстанавливать старые значения дерева из этой ссылки? Ещё раз, что я хочу сделать:
тоесть если нет clone, значит это должно делаться как-то по-другому (разумеется это можно сделать написав обертку наж коллекцией или может быть пройтись в цикле по элементам, но все это выглядит как-то костыльно) Это сообщение отредактировал(а) Тигер - 23.7.2013, 20:29 |
||||
|
|||||
Тигер |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 4.4.2010 Репутация: нет Всего: нет |
вот что предлагают на стековерфлоу
жесть имхо ) |
|||
|
||||
dzaraev |
|
||||||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 12.1.2013 Репутация: нет Всего: 1 |
Давайте по-порядку:
Вы читали про метод MemberwiseClone ? Мне кажется что нет, хотя я даже ссылку вам оставил. Этот метод создаёт shallow-копию объекта и реализован в единственном виде в классе Object. Интерфейс ICloneable это еще какая поддержка, но для интерфейса нужна реализация, которой может стать например MemberwiseClone. Вот пример использования:
Каков был вопрос, таков и ответ. Вы не пояснили - что именно имеется в виду под "сохранять" и "восстанавливать". Если вам нужно сохранить данные куда-то на диск, или передать по сети, то вам нужна сериализация (это ссылка). Если же вам нужно просто на время подменить дереву элементы, а потом вернуть предыдущий набор, то достаточно просто сохранить указатель на значение ItemsSource, как я и предложил. Далее, ваш пример кода - во-первых он показывает, что ваша старая коллекция никуда не сохраняется, а просто болтается в памяти, и зачем тут нужен clone, я не понимаю. Во-вторых, допускаете грубую ошибку - TreeView наследуется от класса ItemsControl, и вот что говорится про этот класс и его свойства Items и ItemsSource:
Короче говоря, если вы до вызова Items.Clear устанавливали ItemsSource (а вы устанавливали, раз пытаетесь его клонировать), то ваш код
Вызовет исключение InvalidOperationException. Нужно либо работать с ItemsSource и с коллекцией, на которую это свойство указывает, либо с коллекцией Items. В случае работы с ItemsSource, если вы хотите очистить дерево от элементов, просто присвойте свойству ItemsSource - null. Учитывая тот код, что вы написали под словами "что я хочу сделать" я полагаю, что именно временная подмена коллекции дерева и было вашей целью и тогда моё предложение в силе, вот так я предлагал сделать:
Далее:
Это не жесть, это вам предложили клонирование через сериализацию (о которой я упоминал выше). Это самый медленный способ клонирования и я его не советую. Если вас все-таки интересует глубокое клонирование данных, вот тут хороший ответ с подборкой вариантов клонирования, возможных в C#. --------------------
Если вопрос решён - помечайте тему. |
||||||||||||||
|
|||||||||||||||
Тигер |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 4.4.2010 Репутация: нет Всего: нет |
Спасибо за подробный ответ!
Под нативной поддержкой, я имел ввиду языковые конструкции. Про MemberwiseClone() я читал ещё до начала топика, про интерфейс после ) Но под мою задачаю они не подходят, потому что интерфейс не реализует коллекция, а MemberwiseClone() protected. Идею вашу я понял, единственной, я изначально работаю с .Items (которео readonly, поэтому и решил для "восстановления" старых значений использовать ItemsSource) Вобщем, я не совсем понимаю как портировать ваш код Ещё раз, что хотелось бы получить
Ещё я пробовал так:
такой вариант работал, только вот oldItems содержало не копии Item'ом, а ссылки на них... Это сообщение отредактировал(а) Тигер - 24.7.2013, 11:00 |
||||
|
|||||
dzaraev |
|
||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 12.1.2013 Репутация: нет Всего: 1 |
Это конечно неправильно. Ну если вы изначально работаете с Items, то уже никуда не "портируете" конечно, у меня используется ItemsSource.
C Items конечно такое не прокатит, т.к. вы сами убедились - это свойство только для чтения.
Конечно ссылки, потому что метод CopyTo просто копирует элементы, т.е. ссылки на них - в ваш массив. О клонировании речи и не идёт. Причем я бы заменил последнюю строчку на заполнение массива Items старыми значениеям, раз уж вы изначально работаете с Items. И тут сразу вопрос - вам точно нужны именно клоны старых элементов? Просто старые ссылки, которые возвращаются на своё место - не подходят, как решение? Если не подходит, то дальше варианта я вижу два - Самостоятельно реализовать клонирование TreeViewItem одним из способов (про способы - пост выше) - Реализовать клонирование данных, которые помещаются в ваши TreeViewItem и при "сохранении" - клонировать именно данные, а не сами элементы TreeViewItem. Сами же элементы TreeViewItem могут настраиваться при помощи шаблона DataTemplate, стилей и т.д. и т.п. Второй вариант - самый адекватный. Практическую необходимость первого же варианта я представляю с трудом. --------------------
Если вопрос решён - помечайте тему. |
||||||||||
|
|||||||||||
Тигер |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 4.4.2010 Репутация: нет Всего: нет |
Ну если я правильно понимаю что имеется ввиду под старыми ссылками, то я так и решил сделать. т.е. программным путем удаляю некоторые Items и тп. Данные клонировать так же не получится, тк. у меня в качестве данных используются объекты (контролы). Разве что писать обертку и уже её помещать в качестве данных в Items... Спасибо! Это сообщение отредактировал(а) Тигер - 24.7.2013, 16:33 |
|||
|
||||
dzaraev |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 12.1.2013 Репутация: нет Всего: 1 |
"Старые ссылки" - это просто ссылки на ваши старые элементы коллекции, которые были в коллекции изначально - вот что я имел ввиду.
Если вопрос решён, пометьте его как рашённый пожалуйста ![]() --------------------
Если вопрос решён - помечайте тему. |
||||
|
|||||
![]() ![]() ![]() |
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |