На заметку! Для свойства Copy Output Directory можно было бы также выбрать вариант Copy if Newer (Копировать, если новее), что позволит сократить время копирования при построении крупных проектов с большим объемом содержимого. В рассматриваемом примере варианта Copy always вполне достаточно.
После компиляции проекта появится возможность щелкнуть на кнопке Show all Files (Показать все файлы) в окне Solution Explorer и просмотреть скопированную папку Images внутри binDebug (может также потребоваться щелкнуть на кнопке Refresh (Обновить)).
Программная загрузка изображения
Инфраструктура WPF предоставляет класс по имени BitmapImage, определенный в пространстве имен System.Windows.Media.Imaging. Он позволяет загружать данные из файла изображения, местоположение которого представлено объектом System.Uri. Добавьте поле типа List<BitmapImage> для хранения всех изображений, а также поле типа int для хранения индекса изображения, показанного в текущий момент:
<b>// Список файлов BitmapImage.</b>
List<BitmapImage> _images=new List<BitmapImage>();
<b>// Текущая позиция в списке.</b>
private int _currImage=0;
Внутри обработчика события Loaded окна заполните список изображений и установите свойство Source элемента управления Image в первое изображение из списка:
private void MainWindow_OnLoaded(
object sender, RoutedEventArgs e)
{
try
{
string path=Environment.CurrentDirectory;
// Загрузить эти изображения из диска при загрузке окна.
_images.Add(new BitmapImage(new Uri($@"{path}ImagesDeer.jpg")));
_images.Add(new BitmapImage(new Uri($@"{path}ImagesDogs.jpg")));
_images.Add(new BitmapImage(new Uri($@"{path}ImagesWelcome.jpg")));
// Показать первое изображение в списке.
imageHolder.Source=_images[_currImage];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Реализуйте обработчики для кнопок Previous и Next, чтобы обеспечить проход по изображениям. Когда пользователь добирается до конца списка, происходит переход в начало и наоборот.
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})
private void btnPreviousImage_Click(
object sender, RoutedEventArgs e)
{
if (--_currImage < 0)
{
_currImage=_images.Count - 1;
}
imageHolder.Source=_images[_currImage];
}
private void btnNextImage_Click(
object sender, RoutedEventArgs e)
{
if (++_currImage >=_images.Count)
{
_currImage=0;
}
imageHolder.Source=_images[_currImage];
}
Теперь можете запустить программу и переключаться между всеми изображениями.
Встраивание ресурсов приложения
Если файлы изображений необходимо встроить прямо в сборку .NET Core как двоичные ресурсы, тогда выберите файлы изображений в окне Solution Explorer (из папки Images, а не binDebugImages) и установите свойство Build Action в Resource (Ресурс), а свойство Copy to Output Directory — в Do not copy (He копировать), как показано на рис. 27.2.
В меню Build (Сборка) среды Visual Studio выберите пункт Clean Solution (Очистить решение), чтобы очистить текущее содержимое папки binDebugImages, и повторно скомпилируйте проект. Обновите окно Solution Explorer и удостоверьтесь в том, что данные в каталоге binDebugImages отсутствуют. При текущих параметрах сборки графические данные больше не копируются в выходную папку, а встраиваются в саму сборку. Прием обеспечивает наличие ресурсов, но также приводит к увеличению размера скомпилированной сборки.
Вам нужно модифицировать код для загрузки изображений в список, извлекая их из скомпилированной сборки:
// Извлечь из сборки и затем загрузить изображения.
_images.Add(new BitmapImage(new Uri(@"/Images/Deer.jpg", UriKind.Relative)));
_images.Add(new BitmapImage(new Uri(@"/Images/Dogs.jpg", UriKind.Relative)));
_images.Add(new BitmapImage(new Uri(@"/Images/Welcome.jpg", UriKind.Relative)));
В таком случае больше не придется определять путь установки и можно просто задавать ресурсы по именам, которые учитывают название исходного подкаталога. Также обратите внимание, что при создании объектов Uri указывается значение Relative перечисления UriKind. В данный момент исполняемая программа представляет собой автономную сущность, которая может быть запущена из любого местоположения на машине, т.к. все скомпилированные данные находятся внутри сборки.