Отображение/изменение свойств объектов в WPF палитре. Проблемы с фокусом.

Автор Тема: Отображение/изменение свойств объектов в WPF палитре. Проблемы с фокусом.  (Прочитано 12817 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Сделал WPF-контрол для отображения/изменения свойств выбранных объектов чертежа определенного типа. Разместил его в палитре. Все вроде неплохо работает, но есть 2 проблемы:
1. Я настроил отображение свойств таким образом, что если у объектов свойства различаются - выводится слово *РАЗЛИЧНЫЕ*. Это слово не отображается, если в поле ввода установить фокус. Проблема в том, что при переходе из палитры обратно в чертеж фокус с поля ввода не снимается, соответственно, слово *РАЗЛИЧНЫЕ* не отображается. Вопрос в том, как отловить событие перехода из палитры обратно в чертеж? Со снятием фокуса по этому событию, думаю, проблем не будет.
2. При изменении свойств в палитре, объекты чертежа изменяются, но их отображение остается прежним. Изменение отображения происходит только при переходе из палитры в чертеж. Как это можно победить?
Вот как это все выглядит:

Буду благодарен за любые идеи как это можно побороть!


Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
1. Для контрола делаешь обработку событий для мышки: когда курсор над контролом и когда вне контрола (MouseEnter и MouseLeave соответственно). В обработчик MouseEnter запихиваешь Focus() (см.п.2). В обработчике события MouseLeave запихиваешь Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView(). Таким образом при переводе мышки в автокад контрол будет терять фокус. Сейчас точно не скажу, но возможно и его дочерние элементы тоже должны терять фокус. Если нет - то ты легко можешь это сделать принудительно
2. Может тоже поможет Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView()? Как только свойства поменялись - фокус получит автокад, элементы изменятся. А как только двинешь мышкой - контрол снова получит фокус (см.п.1). Зрительно ничего не заметишь даже

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78

Отмечено как Решение Дмитрий Загорулькин 19-11-2015, 18:48:09

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Со второй проблемой удалось справиться благодаря подсказке Андрея Бушмана. Для того, чтобы изменения отобразились, после изменения объекта нужно дополнительно вызывать метод Autodesk.AutoCAD.Internal.Utils.FlushGraphics();

P.S. С первой проблемой тоже удалось справиться. Для этого нужно было всего-навсего вместо привязки к свойству TextBox.IsFocused использовать привязку к TextBox.IsKeyboardFocused.
Спасибо за подсказки!

« Последнее редактирование: 19-11-2015, 19:11:35 от Дмитрий Загорулькин »

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Сделал WPF-контрол для отображения/изменения свойств выбранных объектов чертежа определенного типа
я в wpf новичек, а потому интересно, это UserControl или CustomControl? и интересует еще механизм связи с объектами чертежа. Если не сложно можно несколько подробностей.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Это UserControl, что такое CustomControl - я даже не знаю... В этом плане все довольно стандартно - создается UserControl в студии, нашпиговывается контролами и настраиваются отображения и связи с объектами.
А вот механизм связи с объектами чертежа - это отдельная песня. Если вкратце, то последовательность такая:
Для каждого интересующего нас объекта чертежа создаем объект в памяти с теми данными, которые нужно отображать (объект1) -> Создаем объект в памяти (объект 2), который обобщает данные из объектов 1 -> Свойства объекта 2 "биндим" с элементами UserControl.
Все настроено таким образом, что при изменении предвыбора или свойств выбранных объектов (не с помощью разрабатываемого инструмента), данные по восходящей цепочке обновляются в палитре. И наоборот, если изменяются данные в палитре, по нисходящей цепочке передается это действие для изменения каждого выбранного объекта.
Позже, по возможности, сделаю простой проект для демонстрации. Пока на это нет времени.
Все может быть намного проще, если использовать готовый контрол WPF PropertyGrid с доступным свойством SelectedObjects. Но у меня такой возможности нет.


Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
что такое CustomControl - я даже не знаю...
Вот любопытное видео, с примером создания оного: https://vimeo.com/69144418  . ИМХО, толково и понятно изложено.

Оффлайн Volody1983

  • ADN OPEN
  • **
  • Сообщений: 52
  • Карма: 0
Позже, по возможности, сделаю простой проект для демонстрации.
Дмитрий, хотел уточнить удалось сделать пример по демонстрации этого функционала?

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Проект получился не очень простым. Надеюсь, что кому нужно, смогут разобраться.

Оффлайн Volody1983

  • ADN OPEN
  • **
  • Сообщений: 52
  • Карма: 0
Дмитрий Загорулькин,
Спасибо, интересный пример.

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Дмитрий Загорулькин, а не пробовал использовать Windows.Forms.PropertyGrid или Extended WPF Toolkit PropertyGrid? Почему пал вариант создания своего собственного элемента свойств на WPF?

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Изначально использовал как раз Windows.Forms.PropertyGrid. Когда количество костылей к нему превысило все разумные рамки, решил искать альтернативу. Попробуйте, к примеру, сделать так, чтобы при выбранных нескольких объектах с разными значениями свойства, в его поле показывалось "*РАЗЛИЧНЫЕ*", то есть, по аналогии с окном свойств автокада. У меня получилось, но это был сильно обходной путь и, в итоге, все равно работало криво. Ну и таких моментов накопилось много.
Все WPF тулкиты, которые я смог найти, на тот момент были либо платными, либо в бесплатной версии не имели нужного функционала. Возможно, сейчас что-то изменилось.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
или Extended WPF Toolkit PropertyGrid
Конкретно в этом тулките, в бесплатной версии у контрола PropertyGrid не было свойства SelectedItems. Т.е. можно было вывести данные только по одному объекту. Смысла в его использовании из-за этого крайне мало. Политика такая: нужен полноценный PropertyGrid - покупай версию Plus. Покупать этот пакет из-за одного контрола мне показалось неразумным. К тому же, нет полной уверенности, что в нем все будет работать как мне надо.

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Дмитрий Загорулькин, спасибо за разъяснения. Раз уже Вы все попробовали, то не вижу смысла повторять этот путь и сразу перейти к реализации своей палитры. И вот тут второе огромное спасибо за предоставленный пример. Сегодня весь день "прикручивал" его к своим нуждам. Вроде не плохо получается )) Сначала конечно скопипастил, но дальше уже буду подробно разбираться и пилить под свой проект.
Единственное, что у меня вызвало вопрос и я так и не понял почему это происходит у меня и не происходит у вас в вашем примере:
Вот в этом месте:
Код - C# [Выбрать]
  1. public PropertiesPalette()
  2. {
  3.     InitializeComponent();
  4.     AcadHelpers.Documents.DocumentCreated += Documents_DocumentCreated;
  5.     AcadHelpers.Documents.DocumentActivated += Documents_DocumentActivated;
  6.     foreach (Document document in AcadHelpers.Documents)
  7.     {
  8.         document.ImpliedSelectionChanged -= Document_ImpliedSelectionChanged;
  9.         document.ImpliedSelectionChanged += Document_ImpliedSelectionChanged;
  10.     }
  11.     if(AcadHelpers.Document != null)
  12.         ShowPropertiesControlsBySelection();
  13. }
У меня ловится ошибка при загрузке палитры:

Я так-то понимаю, что это на строчке document.ImpliedSelectionChanged -= Document_ImpliedSelectionChanged; происходит, но никак не могу понять, почему в вашем примере не происходит

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
У меня ловится ошибка при загрузке палитры:
Уже обсуждали как-то: http://adn-cis.org/forum/index.php?topic=7555.msg24231#msg24231
но никак не могу понять, почему в вашем примере не происходит
Не знаю, честно :)

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Дмитрий Загорулькин, хотел Вам показать что получается.

Работы еще конечно много. С виду хоть и работает все, но есть несколько неприятных моментов надо которыми еще трудиться и трудиться

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Симпатично! На полноценный PropertyGrid пока не сильно похоже, но допилить можно.

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Симпатично! На полноценный PropertyGrid пока не сильно похоже, но допилить можно.
А полноценный и не нужен) Палитра будет работать только с конкретными свойствами моего "примитива". По сути, тоже самое реализовали в СПДС модуле для 2018 автокада (как минимум в бета-версии).
З.Ы. Забавно, когда тебе приходит идея и пока ты ее обдумываешь - выходит что-то с точно такой-же реализованной идеей

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
На полноценный PropertyGrid пока не сильно похоже, но допилить можно
Вот так лучше ))



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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Конечно, лучше :)
А есть возможность изменять ширину поля?

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
А есть возможность изменять ширину поля?
Хмм.. Не подумал об этом. Я сделал для ColumnDefinition Width="*", чтобы обе колонки были одинаковы. Сделать конечно не сложно, но вот в моем случае не совсем будет удобно, т.к. в палитру добавляются UserControl для конкретного примитива в зависимости от выбранных примитивов. Т.е. если будет два разных примитива выбрано, то отобразятся два Expander для них (у меня пока только один примитив в наличии). И вот в этом случае ширина колонок будет меняться только внутри одного UserControl. Не, конечно можно придумать обходные пути (их, в принципе, всегда можно придумать), но пока-что не вижу смысла