Диалоговое редактирование пользовательских строк

Автор Тема: Диалоговое редактирование пользовательских строк  (Прочитано 7055 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Я храню дополнительные данные в ExtensionDictionary объектов AutoCAD. Одним из таких хранимых параметров является на бор строк. С сами хранением трудностей нет. Они появились, когда я реализовал редактирование этих параметров через палитру AutoCAD (PaletteSet, не стандартная палитра свойств) в PropertyGrid. Для редактирования этих строк я использую атрибут:
Код - C# [Выбрать]
  1.         [RefreshProperties(RefreshProperties.Repaint)]
  2.         [Editor(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
  3.         [Browsable(true)]
  4.         public List<string> Texts { get; set; }
Само редактирование этих строк проходи замечательно - в свойство передаются новые значения. Только вот это не вызывает событие PropertyValueChanged, в котором я и обрабатываю изменение свойств пользователем. Как увязать закрытие окна редактирования строк с изменением свойств объекта?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А какое отношение этот вопрос имеет к AutoCAD .NET API?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Пример по первой ссылке делает тоже самое, что и родное событие EditValue в момент изменения значений в окне редактирования, но это никак не влияет на событие PropertyValueChanged.
Второй пример изучаю.

Вне автокада эту задачу можно решить достаточно легко - обработать все изменения свойства внутри события EditValue. Автокад же усложняет эту задачу своими транзакциями. Именно по этому я и опубликовал этот вопрос тут, где население знает, что такое транзакции автокада.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Вне автокада эту задачу можно решить достаточно легко - обработать все изменения свойства внутри события EditValue. Автокад же усложняет эту задачу своими транзакциями. Именно по этому я и опубликовал этот вопрос тут, где население знает, что такое транзакции автокада.
Так в событии EditValue ты не можешь работать с транзакцией AutoCAD? Требуется блокировка документа. В остальном всё должно быть аналогично тому, как это вне AutoCAD. Если конечно я правильно понял проблему.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Так в событии EditValue ты не можешь работать с транзакцией AutoCAD? Требуется блокировка документа.

Пробовал, но не помогло - возникает ошибка eLockViolation, даже при блокировке документа. Разумеется сегодня вечером я еще раз попробую, может я был очень уставший и не правильно что-то сделал :) Тем не менее, я параллельно ищу альтернативные варианты.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Пробовал, но не помогло - возникает ошибка eLockViolation, даже при блокировке документа.
Если ты заблокировал документ, то такого быть не должно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Я не совсем понимаю контекст, поэтому, практически пальцем в небо.
Вариант №1:
Код - C# [Выбрать]
  1. List<string> _texts;
  2.  
  3. [RefreshProperties(RefreshProperties.Repaint)]
  4. [Editor(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
  5. [Browsable(true)]
  6. public List<string> Texts
  7. {
  8.     get => _texts;
  9.     set
  10.     {
  11.         _texts = value;
  12.         MethodForTextsSet();
  13.     }
  14. }
  15.  
  16. private void MethodForTextsSet()
  17. {
  18.     throw new NotImplementedException();
  19. }
  20.  
Вариант №2:
Код - C# [Выбрать]
  1. ObservableCollection<string> _texts;
  2.  
  3. [RefreshProperties(RefreshProperties.Repaint)]
  4. [Editor(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
  5. [Browsable(true)]
  6. public ObservableCollection<string> Texts
  7. {
  8.     get => _texts;
  9.     set
  10.     {
  11.         _texts = value;
  12.         _texts.CollectionChanged += _texts_CollectionChanged;                
  13.     }
  14. }
  15.  
  16. private void _texts_CollectionChanged
  17.     (object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
  18. {
  19.     throw new NotImplementedException();
  20. }
  21.  

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Дмитрий Загорулькин
Возможно я не прав, но тут всё несколько сложнее с вариантом № 2: https://stackoverflow.com/questions/1427471/observablecollection-not-noticing-when-item-in-it-changes-even-with-inotifyprop/5256827
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Ну тут такая история. Я не знаю, как поступает с коллекцией System.Windows.Forms.Design.StringCollectionEditor. Если редактор заменяет исходную коллекцию на новую, то можно использовать вариант №1. Если же он только изменяет состав коллекции, но без замены самой коллекции (когда метод set действительно не срабатывает), тогда можно работать с вариантом №2. Ну и, в конце-концов, варианты можно объединить.
Сам я уже давно зарекся использовать PropertyGrid, поэтому даже проверить не на чем.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Фух! Решено! Проблема была в транзакции, а точнее надо было использовать "doc.TransactionManager.StartOpenCloseTransaction()" внутри свойства и в событии "doc_SelectionChanged"; именно из-за этого фаталило. Вот полный текст свойства:
Код - C# [Выбрать]
  1.         private List<string> p_texts = new List<string>();
  2.         [PropNameAttribute("strings"), Description(""), PropCategoryAttribute("mtext")]
  3.         [RefreshProperties(RefreshProperties.Repaint)]
  4.         [Editor(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
  5.         [Browsable(true)]
  6.         public List<string> Texts
  7.         {
  8.             get
  9.             {
  10.                 Document doc = Application.DocumentManager.MdiActiveDocument;
  11.                 Database db = doc.Database;
  12.                 Editor ed = doc.Editor;
  13.  
  14.                 bool f = false;
  15.  
  16.                 try
  17.                 {
  18.                     using (DocumentLock dcl = doc.LockDocument())
  19.                     {
  20.                         using (Transaction trans = doc.TransactionManager.StartOpenCloseTransaction())
  21.                         {
  22.                             PromptSelectionResult selected = ed.SelectImplied();
  23.  
  24.                             if (selected.Value != null && selected.Value.Count == 1)
  25.                             {
  26.                                 Entity ent = (Entity)trans.GetObject(selected.Value[0].ObjectId, OpenMode.ForRead);
  27.  
  28.                                 if (ent is Polyline)
  29.                                 {
  30.                                     Polyline pline = (Polyline)ent;
  31.  
  32.                                     if (!pline.IsWriteEnabled)
  33.                                     {
  34.                                         f = true;
  35.                                         pline.UpgradeOpen();
  36.                                     }
  37.  
  38.                                     MultiTextLeaderClass mt;
  39.                                     if (XDataClass.XDataRead(pline, out mt))
  40.                                     {
  41.                                         mt.Texts = Texts;
  42.                                         XDataClass.XDataUpdate(ref pline, mt);
  43.                                         pline.RecordGraphicsModified(true);
  44.                                     }
  45.  
  46.                                     if (f)
  47.                                         pline.DowngradeOpen();
  48.                                 }
  49.                             }
  50.  
  51.                             trans.Commit();
  52.                         }
  53.                     }
  54.                 }
  55.                 catch { }
  56.  
  57.                 Autodesk.AutoCAD.Internal.Utils.FlushGraphics();
  58.  
  59.                 return p_texts;
  60.             }
  61.             set { p_texts = value; }
  62.         }

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Алексей Терно
В методе доступа get модифицировать объект из базы??? Хм...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
В методе доступа get модифицировать объект из базы??? Хм...
Мне и самому такой подход не очень нравится, но других вариантов у меня пока нет ((