Как WinForms PropertyGrid находит пользовательские преобразователи типов во внешних библиотеках? - PullRequest
0 голосов
/ 17 мая 2019

У нас есть пользовательский контроль. В некоторых свойствах этого элемента управления используются настраиваемые преобразователи типов и редакторы типов пользовательского интерфейса, и они реализованы в отдельной библиотеке времени разработки. Эти преобразователи типов определяются с использованием строкового синтаксиса атрибутов TypeConverter и Editor, например:

[TypeConverter("<full class name>, <library name>, Version=<version>")]
public CustomType Property1
{
    // property implementation
}

Когда мы отображаем свойства нашего пользовательского элемента управления в стандартном элементе управления PropertyGrid из пакета WinForms в скомпилированном приложении, соответствующие преобразователи типов и редакторы типов пользовательского интерфейса из нашей библиотеки времени разработки обнаруживаются только тогда, когда мы помещаем эту библиотеку DLL в папка с приложением exe. Мы не хотим дублировать DLL времени разработки в этой папке по некоторым причинам. Есть ли другой способ сообщить элементу управления PropertyGrid, где он может найти DLL-файл времени разработки, на которую ссылается этот путь?

1 Ответ

1 голос
/ 18 мая 2019

Вы можете использовать любую из следующих опций:

  • Установите сборку в GAC и украсьте свойство следующим образом (используйте полное имя вашей сборки). Как уже упоминалось в комментариях Ганса, я также считаю, что это самый достойный способ:

    [TypeConverter("MyAssembly.MyClassTypeConverter, MyAssembly, Version=1.0.0.0," +
        " Culture=neutral, PublicKeyToken=8ac69aab03bb290e")]
    public MyClass MyClass { get; set; }
    
  • Скопируйте сборки в папку вашего приложения и украсьте свойство следующим образом.

    [TypeConverter("MyAssembly.MyClassTypeConverter, MyAssembly")]
    public MyClass MyClass { get; set; }
    
  • В случае наличия известного местоположения для сборок вы можете обработать событие AppDomain.AssemblyResolve и загрузить сборку. Например, если в папке вашего приложения есть папка assemblies, содержащая сборку, вы можете добавить следующий код в метод main перед Application.Run:

    AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
        Assembly.LoadFrom(Path.Combine(Application.StartupPath,
            "assemblies", $"{e.Name}.dll"));
    

    Я полагаю, у вас есть объявление свойства:

    [TypeConverter("MyAssembly.MyClassTypeConverter, MyAssembly")]
    public MyClass MyClass { get; set; }
    
  • Как уже упоминалось в комментариях TnTinMn, в случае наличия известного местоположения для сборок, вы также можете загрузить сборки без написания кода, зарегистрировав известную папку в вашем app.config, используя probing тег или codebase тег. Например, если в папке приложения есть папка assemblies, в которой содержится сборка:

    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="assemblies"/>
      </assemblyBinding>
    </runtime>
    

    Полагаю, у вас есть объявление о недвижимости:

    [TypeConverter("MyAssembly.MyClassTypeConverter, MyAssembly")]
    public MyClass MyClass { get; set; }
    

Примечание: Ни один из вышеперечисленных вариантов не требует добавления ссылки на сборку, которая содержит преобразователь типа.

...