Подтвердить что ты не робот

Проблема с общими ресурсами WinForms для проектов в Visual Studio

Я переместил все ресурсы изображений в большом многопроектном решении в новый проект, специально созданный для общих ресурсов.

Добавление новой ссылки на другие проекты, в которых используются общие изображения, работает должным образом. Изображение в выбранной кнопке ниже продолжает появляться в конструкторе, но с проблемами.

В VS Designer я не могу выбрать общие ресурсы в редакторе изображений, вместо этого нужно вручную редактировать код дизайнера.

В частности, в диалоговом окне "Редактор изображений" (доступ к которому осуществляется из свойства "Изображение" существующего элемента управления) я выбираю "Выбрать из файла/ресурса...", чтобы открыть диалоговое окно "Выбор ресурса" (показано). Там, где я использовал доступ ко всем локальным ресурсам проекта (Resources.resx), я хотел бы сейчас добавить доступ к новому проекту общих ресурсов. В идеале, я бы добавил второй элемент в раскрывающемся списке, который переключается на resx для проекта общих ресурсов.

Как это может быть сделано? Есть ли способ лучше?

alt text

4b9b3361

Ответ 1

Я смог поделиться файлом resx между проектами и использовать его в конструкторе в VS 2008 SP1 (не знаю, другие версии). В отличие от других подходов, здесь ресурсы статически и динамически совместно используются, поэтому во время выполнения действительно одна копия общих ресурсов. Нет хранения или траты памяти, и это легко поддерживать с тоннами проектов.

Следуйте инструкциям и скажите, работает ли он для вас:

  • Создать проект класса Ресурсы;
  • Создайте файл ресурсов (зайдите в Свойства → Ресурсы проекта);
  • Переместите файл ресурсов (по умолчанию Resources.resx) в корень проекта;
  • Переименуйте файл ресурсов Resources.resx → GlobalResources.resx;
  • Измените модификатор файла ресурсов на Public (дважды щелкните файл ресурсов, "Access Modifier" → "Public");
  • Скопируйте любой файл ресурса в корневой каталог проекта;
  • Добавьте любой ресурс в файл ресурсов, используя "Добавить существующий файл" и выбрав ресурсы в корневом каталоге проекта.

Проект в обозревателе решений должен выглядеть следующим образом:

enter image description here

Теперь в любом проекте вам нужен файл resx, которым вы хотите поделиться:

  • Добавить проект "Ресурс" как зависимость;
  • Отредактируйте вручную файл проекта (*.csproj) и добавьте следующие строки в файл ресурсов ItemGroup (создайте файл локальных ресурсов, если вы хотите его увидеть):

    <ItemGroup>
      ...
      <EmbeddedResource Include="..\Resources\GlobalResources.resx">
        <Link>GlobalResources.resx</Link>
        <Generator>ResXFileCodeGenerator</Generator>
        <LastGenOutput>GlobalResources.Designer.cs</LastGenOutput>
        <CustomToolNamespace>Resources</CustomToolNamespace>
      </EmbeddedResource>
      ...
    </ItemGroup>
    

Очевидно, что атрибут "Включить" должен быть правильным относительным путем к GlobalResources.resx.

  • Используйте ресурсы в конструкторе, как вы просили.

В моем проекте следующие строки создаются и добавляются в проект автоматически, когда я делаю это:

<Compile Include="..\Resources\GlobalResources.Designer.cs">
  <Link>GlobalResources.Designer.cs</Link>
  <AutoGen>True</AutoGen>
  <DesignTime>True</DesignTime>
  <DependentUpon>GlobalResources.resx</DependentUpon>
</Compile>

Если они не добавлены, добавьте их вручную.

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

enter image description here

Последние два шага:

  • Нажмите на ссылку "GlobalResources.resx" и в свойствах установите "None" в качестве "BuildAction". "Пространство имен пользовательских инструментов" уже должно быть установлено на "Ресурсы";

enter image description here

  • Нажмите на ссылку "GlobalResources.Designer.resx" и в свойствах установите "None" в качестве "BuildAction".

enter image description here

И все готово: к этому моменту вы действительно сможете использовать ресурсы, которые вы добавили в общий ресурс в конструкторе, выбрав "GlobalResources.resx" в диалоговом окне "Файл ресурсов проекта" вашего вопроса. И как он сказал, что действительно поделился даже во время выполнения! На панели "Свойства" вы должны увидеть полное пространство имен и класс внешнего проекта. Если вы удалите зависимость от проекта "Ресурс", он даже не скомпилируется. Если это не работает для вас, настаивайте до тех пор, пока это не сработает, и в случае, скажите мне, где руководство неверно. Это должно работать! Дай мне знать.

Ответ 2

В последнее время я столкнулся с той же проблемой. Посмотрел документацию по MS, но не нашел хороших решений. В конечном итоге я смог получить редактор изображений в дизайнере WinForms для распознавания файлов ресурсов из других проектов с использованием метода, описанного ниже. Это хаки - если у кого-то есть более чистое решение, которое они хотят разделить, пишите. Я тестировал это только на VS 2008.

Прежде чем начать, я должен сказать, что если вы просто хотите, чтобы элементы в файле Resource.resx были доступны для других проектов, вы можете просто отредактировать его свойства и установить модификатор доступа для сгенерированного класса для публики, чтобы он использовал PublicResXFileCodeGenerator, Гимнастика ниже нужна только в том случае, если вы хотите, чтобы дизайнеры WinForms собирали изображения внутри этого файла ресурсов, как описано в сообщении выше от Дугласа.

Скажите, что ваше решение имеет следующий макет. Здесь важно использовать пространство имен по умолчанию для различных проектов (щелкните правой кнопкой мыши по проекту node в обозревателе решений → Свойства → вкладка приложения), поэтому я положил это в скобки после названий проектов.

  • MySolution
    • SharedProject (по умолчанию namespace = SharedProject)
      • SharedProject.csproj
    • WinFormsProject1 (по умолчанию namespace = WinFormsProject1)
      • WinFormsProject1.csproj
    • WinFormsProject2 (пространство имен по умолчанию = WinFormsProject2)
      • WinFormsProject2.csproj

Вы хотите создать файл ресурсов в SharedProject, содержащий изображения, которые могут использоваться WinFormsProject1 и WinFormsProject2.

Сначала создайте новый файл ресурсов в корневом каталоге SharedProject, позвоните ему SharedResources.resx. Важно, чтобы этот файл использовал ResXFileCodeGenerator, а не PublicResXFileCodeGenerator по причинам, которые станут понятнее позже.

Измените SharedResources.resx в Visual Studio и добавьте ресурсы изображения, которые вы хотите разделить. Visual Studio также должен сгенерировать файл класса для вас в SharedProject с именем SharedResources.designer.cs.

Теперь ваше решение должно выглядеть следующим образом:

  • MySolution
    • SharedProject (по умолчанию namespace = SharedProject)
      • SharedProject.csproj
      • SharedResources.resx
      • SharedResources.Designer.cs
    • WinFormsProject1 (по умолчанию namespace = WinFormsProject1)
      • WinFormsProject1.csproj
    • WinFormsProject2 (пространство имен по умолчанию = WinFormsProject2)
      • WinFormsProject2.csproj

Если вы открываете SharedProject.csproj с помощью текстового редактора, вы должны увидеть следующие записи:

<EmbeddedResource Include="SharedResources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>SharedResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Compile Include="SharedResources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>SharedResources.resx</DependentUpon>
</Compile>

Теперь вам нужно сделать доступными ресурсы внутри WinFormsProject1. Для этого вам понадобится отредактировать WinFormsProject1.csproj в текстовом редакторе, потому что некоторые свойства, которые необходимо установить, не отображаются внутри Visual Studio.

Откройте файл WinFormsProject1.csproj и добавьте следующее внутри группы элементов:

<Compile Include="..\SharedProject\SharedResources.Designer.cs">
    <Link>SharedResources.Designer.cs</Link>
    <AutoGen>True</AutoGen>
    <DesignTime>True</DesignTime>
    <DependentUpon>SharedResources.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="..\SharedProject\SharedResources.resx">
    <Link>SharedResources.resx</Link>
    <Generator>ResXFileCodeGenerator</Generator>
    <LastGenOutput>SharedResources.Designer.cs</LastGenOutput>
    <CustomToolNamespace>SharedProject</CustomToolNamespace>
    <LogicalName>SharedProject.SharedResources.resources</LogicalName>
</EmbeddedResource>

Ключевыми здесь являются CustomToolNamespace и Логическое имя. По умолчанию Visual Studio использует пространство имен по умолчанию для проекта, чтобы назвать ресурсы и сгенерировать файл *.Designer.cs. Поскольку SharedProject и WinFormsProject1 имеют разные пространства имен по умолчанию, поведение по умолчанию заставляет ресурс, встроенный в WinFormsProject1, быть несовместимым с файлом *.Designer.cs, который находится внутри SharedProject. Этого можно предотвратить, переопределив CustomToolNamespace и LogicalName.

Теперь сделаем то же самое для WinFormsProject2.csproj. Вернитесь в Visual Studio. Он заметит, что вы изменили файлы csproj и попросите перезагрузить проекты - выберите "перезагрузить". Вы должны обнаружить, что теперь вы можете выбирать изображения из SharedResources.resx при разработке форм как в WinFormsProject1, так и в WinFormsProject2.

По сути, все это означает, что VS включает файл SharedResources.resx из SharedProject в проектах WinFormsProject1 и WinFormsProject2. Существует только один исходный файл .resx(в SharedProject), но при компиляции решения на самом деле будут три одинаковых класса SharedProject.SharedResources, по одному в каждой из трех сборок, но поскольку у всех есть внутренняя видимость, они не будут вмешиваться друг с другом, даже если вы добавляете ссылку между проектами.

Ответ 3

СОВМЕСТНЫЕ РЕСУРСЫ МЕЖДУ ПРОЕКТАМИ В VS2012

за 3 простых шага, используя только конструктор!

  • создайте проект и добавьте ресурсы для совместного использования как обычно
  • создайте еще один проект и добавьте в ссылку ссылку resources.resx первого проекта в диалоговом окне "Добавить существующий элемент", доступный из контекстного меню
  • выберите нужные изображения из файла связанных ресурсов; это можно выбрать в раскрывающемся меню "файл ресурса проекта" в диалоговом окне "выбрать ресурс", доступном из панели свойств

VOILA!

Ответ 4

Вам нужен только новый проект класса с файлом RESX, в который вы включаете ресурсы (изображения, тексты и т.д.). После этого в других проектах добавьте ссылку на это и используйте имя класса ресурсов, чтобы получить доступ к требуемому ресурсу, например: Project.SharedImages.Upload_64x64 (в результате получается растровое изображение, готовое к использованию в этом случае)

Ответ 5

Для Visual Studio 2015 +

Существует простой, простой способ, который не поддерживается в пользовательском интерфейсе VisualStudio. Поэтому, если вы не боитесь редактировать файлы проекта, читайте дальше.

Если вы еще этого не сделали, добавьте новый новый проект в решение. Добавить Новый общий проект

Если вы еще этого не сделали, включите новый общий проект в качестве общей ссылки проекта на ваш периферийный проект. введите описание изображения здесь

Обратите внимание, что этот общий проект включен в периферийный проект (.csproj файл) прямо следующим образом:

<Import Project="..\Common\Common.projitems" Label="Shared" />

Таким образом, несмотря на то, что VS UI не раскрывает его, все в общем проекте (.projitems файл) включается непосредственно в периферийный проект. Добавление следующих описаний ресурсов в общий проект (.projitems file) будет включать их непосредственно в ваш периферийный проект. Но поскольку элемент Resource не поддерживается VS UI для общих проектов, эти файлы будут скрыты и проигнорированы в среде IDE.

<ItemGroup>
  <Resource Include="$(MSBuildThisFileDirectory)Resources\one 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\one 64x64.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\one.ico" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\two 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\three 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\four 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\five 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\six 16x16.png" />
</ItemGroup>

Наконец, в то время как ресурсы вашего периферийного проекта могут иметь относительные пути (например, ".\Resources\main.ico"), эти ресурсы скомпилированы в ваш периферийный проект с базовыми идентификаторами, а не абсолютными или относительными. например:.

<Window x:Class="Common.Shared"
  ...
  Icon="one.ico">
  <Window.Resources>
    <ResourceDictionary>
      <BitmapImage x:Key="one64" UriSource="one 64x64.png"/>
    </ResourceDictionary>
  </Window.Resources>