WPF Image 컨트롤 Source 속성 변경 (Code Behind, Resource 활용)
개인 작업으로 WPF 프로젝트를 진행하던 게 있었는데, 개발한 앱이 실시간으로 이미지를 변경해줘야 하는 기능이 있었다. 그 기능을 구현하기 위해 XAML에 Style Trigger 등을 활용해서 Image Control이 참조하고 있는 Source를 변경하려고 했었는데, Trigger를 사용하는 방법이 내가 해결해야 하는 문제와는 맞지 않아, 적용하지 못했다.
결국 Code behind 방식으로 Code로 구현을 했어야만 하는 상황이었는데, 해결한 방법에 대해 정리해보려고 한다.
블로그 포스팅 용도로 간단하게 프로젝트가 구성된 내용만 확인하고, 바로 Code-Behind 방법으로 Image Control의 Source를 바로 변경하는 방법을 살펴보자.
프로젝트 구성
샘플로 아래와 같은 순서대로 프로젝트를 만들었다.
위 방법으로 생성된 기본 프로젝트에 테스트를 위한 이미지 두 개를 다운로드하고 리소스로 추가하였다. 여러 앱에서 활용할 수도 있는 아이콘인 Material Design Icon을 사용해서 일단 샘플 작업을 진행했다. (https://fonts.google.com/icons)
Material Symbols and Icons - Google Fonts
Material Symbols are our newest icons consolidating over 2,500 glyphs in a single font file with a wide range of design variants.
fonts.google.com
그리고 기본으로 생성되는 MainWindow.xaml에는 아래와 같이 작성했다.
<Window x:Class="WPF_Test_App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_Test_App"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Border BorderBrush="Black" Margin="100,50" BorderThickness="2" CornerRadius="6" Padding="5" Cursor="Hand" MouseLeftButtonDown="Border_MouseLeftButtonDown">
<Image x:Name="imgTestSource" Source="/Resources/menu_close.png"/>
</Border>
</Grid>
</Window>
약간의 Round 처리가 된 Border 안에 Image 컨트롤을 배치하고 기본 Image Source는 Resource로 등록한 menu_close image가 나타나게 했다. 그리고 Border를 클릭했을 때, 즉 Mouse Left Button Down을 했을 때 이미지를 변경하는 예제를 진행해보려고 한다.
Code-Behind 방법으로 Image 컨트롤 Source 변경하기
코드는 아래와 같다. 매우 간단하다.
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private bool isMenuClick { get; set; }
public MainWindow()
{
InitializeComponent();
}
/// <summary>
/// Border 내부 영역에서 Mouse Left Button Down 이벤트가 발생하면 (클릭)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var uri = string.Format("pack://application:,,,/{0};component/{1}",
System.Reflection.Assembly.GetExecutingAssembly().GetName(),
"Resources/");
if (this.isMenuClick)
{
this.imgTestSource.Source = new BitmapImage(new Uri(uri + "menu_close.png"));
}
else
{
this.imgTestSource.Source = new BitmapImage(new Uri(uri + "menu_open.png"));
}
isMenuClick = !isMenuClick;
}
}
Border(Image)를 클릭할 때마다 이미지가 토글되게끔 예제를 작성하였다. 그를 위해 isMenuClick이라고 하는 변수를 하나 선언하여 활용하였다.
그리고 Code-Behind로 Image의 Source를 변경할 때는 uri로 참조하는 이미지 경로를 직접 지정해줘야 하는데, 양식은 위에 코드에서 보는 것과 같이 "pack://application,,,/{ Assembly Name };component/{ 참조하는 Resource 파일 경로 }"로 입력해 주면 된다.
그리고 Uri 클래스와 BitmapImage를 사용해서 Resource 폴더의 이미지를 Bitmap 정보로 읽어 바로 Source로 지정하는 것이 전부다.
아래는 프로그램 동작 결과다.