Дизайнер, отказывающийся от контроля пользователя - PullRequest
8 голосов
/ 21 января 2011

У меня есть C ++ 'Control Library Project', скомпилированный с использованием / CLR. Внутри этого проекта есть пользовательский элемент управления, который выполняет вызов собственной библиотеки DLL. Этот пользовательский элемент управления появляется в панели инструментов дизайнера, как и должен, но я не могу затем перетащить его на форму. Без ссылки на DLL пользовательский элемент управления может использоваться нормально, но со ссылкой я просто получаю сообщение «Не удалось загрузить элемент панели инструментов» при попытке его использовать.

Собственный вызов функционален и не наносит вреда пользовательскому элементу управления в любом случае. Пользовательский элемент управления может хорошо просматриваться в конструкторе с включенным вызовом DLL. Кроме того, если элемент управления добавляется вручную в форму и выполняется как программа, он также будет отображаться нормально.

Это заставляет меня подозревать, что проблема в том, что Visual Studio Designer нужно знать, где находится эта нативная DLL. Но я не уверен, как сказать это, или где поместить DLL, чтобы он мог ее найти. Насколько я знаю, в настройках проекта нет способа ссылаться на собственную DLL. Поэтому для меня имеет смысл, что дизайнер просто жалуется, потому что это не может оштрафовать его.

Есть ли способ заставить эту работу?

Ответы [ 6 ]

10 голосов
/ 29 января 2011

К сожалению, вы столкнулись с «ошибкой по замыслу» в VS (или, другими словами, с «функцией»).

Ваше подозрение, что проблема заключается вдизайнер Visual Studio, которому нужно знать, где находится собственная DLL, имеет право частично вправо.Дело не в незнании его местоположения, а в том, что конструктор не может отразить сборки со смешанным режимом (те, которые содержат как управляемый, так и собственный код) для создания экземпляра элемента управления.Это приводит к тому, что на панели инструментов отображается ошибка, которую вы заметили.

Обходной путь - скомпилировать исходные файлы C ++, используя /clr:pure, для создания чисто управляемого EXE-файла.


Другая возможность (также «ошибка по замыслу» в VS) заключается в том, что элемент управления, который вы пытаетесь добавить, был скомпилирован как 64-разрядный компонент.Поскольку Visual Studio является 32-разрядным процессом, он может выполнять только 32-разрядные модули.Хотя он позволяет вам добавить ссылку на 64-битную сборку, он на самом деле не может JIT скомпилировать эту 64-битную сборку и выполнить ее в процессе.

Обходной путь здесь заключается в компиляции вашей сборки пользовательского элемента управления, используя "AnyCPU ", которая заставит его выполняться как 32-разрядный процесс в 32-разрядной среде и как 64-разрядный процесс в 64-разрядной среде.На самом деле, это лучшее из обоих миров, если вы правильно написали свой код.


Наконец, если ничего из этого не работает, всегда есть возможность обойти конструктор,Вы по-прежнему можете написать код, необходимый для создания экземпляра пользовательского элемента управления и установить его свойства в инициализаторе формы.Все, что вы потеряете, - это возможность использовать элемент управления внутри дизайнера в Visual Studio.Все будет работать как положено во время выполнения.

3 голосов
/ 18 октября 2012

Свяжите вашу библиотеку с параметром /DELAYLOAD:"your_native.dll ". Это решило ту же проблему для меня.

1 голос
/ 14 сентября 2011

Я обнаружил, что это похоже на похожую проблему?

https://connect.microsoft.com/VisualStudio/feedback/details/388107/winforms-designer-fails-to-load-managed-dll-having-unmanaged-dependencies#details

Таким образом, MS, кажется, официально говорит об обновлении с VS2008 до VS2010 в качестве обходного пути.

Вы когда-нибудь находили другой обходной путь?

Это проблема, с которой я сейчас сталкиваюсь в VS2008 с управляемым проектом C # .net с использованием управляемого проекта оболочки C ++ с использованием неуправляемого проекта C ++.

Мне определенно кажется, что временные сборки конструктора, которые использует Visual Studio, представляют собой проблему - он загружает обнаруженную сборку оболочки зависимостей во временную папку, но не неуправляемые зависимости этой сборки оболочки. Я вижу, это в C: \ Users \ Имя пользователя \ AppData \ Local \ Microsoft \ VisualStudio \ 9.0 \ ProjectAssemblies. Когда я пытаюсь загрузить конструктор, там создается новая папка с управляемой DLL, но без неуправляемых зависимостей. К сожалению, я не могу понять, что говорит человек из вопроса, приведенного выше по ссылке Microsoft, - это обходной путь с использованием $ (TargetDir).

0 голосов
/ 24 января 2013

У меня была проблема, похожая на эту, которая может быть такой же, как у вас (кто знает, сколько вещей может быть причиной этого?), В основном я не мог передать элементы управления конструктору, но существующие элементы управления работали нормально и производство и тестирование.

Для протокола, вот мое решение:

1) Измените настройки вашего решения на x86. Это позволило мне установить контроль над дизайнером, переместить его и т. Д. 2) Когда закончите, вы можете вернуться к AnyCPU или x64. Я на самом деле использую конструктор только для упрощения установки нескольких значений, и кажется, что все 32/64 бит вызывает проблемы.

0 голосов
/ 29 января 2011

Мне кажется, что управление со ссылкой на нативную DLL не выполняется, потому что Visual Studio не может загрузить его.Попробуйте установить переменную среды PATH либо глобально, либо для исполняемого файла Visual Studio при его запуске.Если это не помогло, попробуйте отладить поведение вашего элемента управления во время разработки, и вы сможете найти проблему.

0 голосов
/ 26 января 2011

Что попробовать:

VS2010: скопировать dll в папку Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies.

VS2008, VS2010: скопировать dll в папку AppData\Local\Microsoft\VisualStudio\<version>\ProjectAssemblies\.

...