А в чем проблема взять ObjectId как строку и сохранить её в XData как строку?Не кошерно :) Собственно, с тем же успехом можно и как long сохранить. Но как считать обратно-то?
А в чем проблема взять ObjectId как строку и сохранить её в XData как строку?В новой сессии все ObjectId пересчитываются и, соответственно, записанные таким образом данные становятся недействительными.
Собственно, все чего мне не хватало - этолучше
Код - C# [Выбрать]
id = db.GetObjectId(false, hdl, 0);
Значит просто нолик последний непонятный параметр.
Странно, что нет прямого пути, ведь изрядная доля всех словарей в БД заполнена ссылками на объекты. Ну раз нет, то пойдем в обход.В расширенных данных (Xdata) нельзя хранить ссылки на ObjectId в отличие от XRecord. Хранение Handle в ExtendedDataAsciiString имеет свои плюсы и минусы. Например, команда _WBLOCK создаёт новый чертеж с пересчитанными метками. В ExtendedDataAsciiString метка пересчитана не будет и вероятнее всего она будет ссылаться или на неправильный объект или вообще на "ничто". Хранение в ExtendedDataHandle имеет тоже свои недостатки. При _WBLOCK метки пересчитаются, а вот что будет при обычной операции копирования? В этом случае метка не пересчитается и новый примитив будет ссылаться на оригинал, а не на копию. Так что потребуется еще некая логика обработки таких ситуаций.
А если я попытаюсь хранить пары id связанных объектов в словарях.Не думаю. В любом случае есть проблемы логики. Универсального решения нет и быть не может.
Спасибо. Я отчетливо понимаю проблемы связанные с хранением ссылок и до сих пор мне удавалось избежать этого. Подумаю как избежать и в этот раз.
А если я попытаюсь хранить пары id связанных объектов в словарях. Это улучшит ситуацию? Какие типы DxfCode предпочтительно использовать?
Эх... Смешно до слез! Сколько времени я потратил на разработку этого инструмента! Сколько багов отловили пользователи! Сколько нервов это стоило и мне и им! А оказалось, что это просто велосипед. И все уже давно сделано и работает как надо.http://adn-cis.org/forum/index.php?topic=743.105 (http://adn-cis.org/forum/index.php?topic=743.105)
Принцип прост: берем Id объекта и добавляем его в запись словаря другого объекта под кодом HardPointerId или SoftPointerId. И всё, больше ничего делать не надо! Все остальное берут на себя внутренние механизмы AutoCAD! Никаких обработчиков событий, актуализаторов и прочей головной боли! :-\
Этот вариант - не то?Вариант не универсален, как я указывал дальше в обсуждении, хотя в некоторых случаях может быть полезен.
public static void AddVal(this ResultBuffer rb, ObjectId value)
{
rb.Add(new TypedValue((int)DxfCode.ExtendedDataHandle, value.Handle));
}
Boolean isValidHandle = db.TryGetObjectId(hdl, out id);
а если записывать все же вот такЭтого делать не следует, так как AutoCAD преобразовывает при некоторых операциях значения в группе 1005. Поэтому в какой-то момент вместо того значения, которое там было ты можешь получить совсем другое.
следующее выдает ошибку на этапе преобразования object в Handle - заданное приведение недопустимоДумаю что вместо :
Код - C# [Выбрать]
Handle[] handleArr = dataList.FindAll(x => x.TypeCode == 1005).Select(x => (Handle)x.Value).ToArray();
выше вы говорили что он пересчитывает например при WBlock.. это ведь оправданно?Универсального правила нет. Я не знаю для чего ты собраешься хранить Handle'ы и что будешь с ними делать, какие операции возможны с этим объектом. Как вариант можешь хранить и в группе 1000 и в группе 1005 и сравнивать результаты.
или бывают случаи когда он некорректно пересчитывает?
т е лучше хранить строку?
тогда вот так сделал (сохраняю long как строку)Код - C# [Выбрать]
Handle[] handleArr = typeList.FindAll(x => x.TypeCode == 1000).Select(x => new Handle(long.Parse((string)x.Value))).ToArray();