클래스 내부의 Property가 변경 되었을 때, 메인 컨트롤에 표시 될 수 있게 하는 바인딩 방법을 정리하였습니다.
순서대로 하나씩 정리해보겠습니다!
제가 테스트한 구조는 아래와 같습니다.(쉬운 이해를 위해 아래와 같이 구성하였습니다.)
1. MainWindow.xaml : 컨트롤을 생성하고 값을 표시하는 곳
2. MainWindow.xaml.cs : 버튼을 눌렀을 때, TestInfo 클래스 내부의 Property 값을 변경
3. Data.cs : Singleton 패턴이 적용된 Data 클래스
4. TestInfo.cs: Data 클래스를 통해 접근이 가능한 클래스, 이 클래스 내부에 Property가 들어있다.
MainWindow.xaml
<Window x:Class="WPF_Project.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_Project"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Closed="Window_Closed">
<Window.Resources>
<Style x:Key="StdLabel" TargetType="Label">
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
<Setter Property="VerticalContentAlignment" Value="Center"></Setter>
<Setter Property="FontSize" Value="15"></Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Label x:Name="lbltest1" Content="{Binding TEST1}" Style="{StaticResource StdLabel}"></Label>
<Label Grid.Row="1" x:Name="lbltest2" Content = "{Binding TEST2}" Style="{StaticResource StdLabel}"></Label>
<Label Grid.Row="2" x:Name="lbltest3" Content = "{Binding TEST3}" Style="{StaticResource StdLabel}"></Label>
<Label Grid.Row="3" x:Name="lbltest4" Content = "{Binding TEST4}" Style="{StaticResource StdLabel}"></Label>
<Button Grid.Column="1" x:Name="btnValue" Margin="20" Click="btnValue_Click">Value 변경</Button>
</Grid>
</Window>
Value변경 버튼을 누르면 TEST1, TEST2, TEST3, TEST4 속성이 변경되고 컨트롤에 표시되게 됩니다.
MainWindow.xaml.cs(작업코드)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPF_Project
{
/// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//바인딩을 위해서는 DataContext에 객체를 등록해야합니다.
this.DataContext = Data.Instance.Test;
//TestInfo 클래스에서 PropertyChanged 이벤트가 발생하면 Test_PropertyChanged가 수행됩니다.
Data.Instance.Test.PropertyChanged += Test_PropertyChanged;
}
//이벤트가 발생한 PropertyName에 따라서 출력합니다.
private void Test_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if(e.PropertyName == "TEST1")
{
Console.WriteLine("1: {0}", Data.Instance.Test.TEST1);
}
else if (e.PropertyName == "TEST2")
{
Console.WriteLine("2: {0}", Data.Instance.Test.TEST2);
}
else if (e.PropertyName == "TEST3")
{
Console.WriteLine("3: {0}", Data.Instance.Test.TEST3);
}
else if (e.PropertyName == "TEST4")
{
Console.WriteLine("4: {0}", Data.Instance.Test.TEST4);
}
}
//버튼을 클릭했을 때 값을 계속 변경하기 위한 기능
int cnt = 0;
private void btnValue_Click(object sender, RoutedEventArgs e)
{
Data.Instance.Test.TEST1 = string.Format("test{0}", cnt);
Data.Instance.Test.TEST2 = string.Format("test{0}", cnt + 1);
Data.Instance.Test.TEST3 = string.Format("test{0}", cnt + 2);
Data.Instance.Test.TEST4 = string.Format("test{0}", cnt + 3);
if(cnt == 50)
{
cnt = 0;
}
else
{
cnt++;
}
}
//Window 종료 시 이벤트 해제
private void Window_Closed(object sender, EventArgs e)
{
Data.Instance.Test.PropertyChanged -= Test_PropertyChanged;
}
}
}
Data.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace WPF_Project
{
public class Data
{
//Singleton 패턴 적용
//하나의 인스턴스만 사용하기 위한 패턴이다!
//volatile은 컴파일러가 최적화하지 못하게 하는 것이다.
private static object syncIns = new object();
private static volatile Data instance;
public static Data Instance
{
get
{
if(instance == null)
{
lock(syncIns)
{
if(instance == null)
{
instance = new Data();
}
}
}
return instance;
}
}
public Data()
{
}
//TestInfo 클래스 선언
private TestInfo testInfo = new TestInfo();
public TestInfo Test
{
get
{
return testInfo;
}
}
}
}
TestInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace WPF_Project
{
//Property가 변경되었다는 것을 알리는 인터페이스 상속
public class TestInfo : INotifyPropertyChanged
{
//PropertyChanged 이벤트 핸들러를 선언한다.
public event PropertyChangedEventHandler PropertyChanged;
//Property가 변경되었을 때 동기를 맞추기 위한 변수
private static object syncIns = new object();
private string test1 = string.Empty;
public string TEST1
{
get
{
return test1;
}
set
{
//test1 값이 변경되었을 때, TEST1 속성 변경 이벤트 발생
if (test1 != value)
{
test1 = value;
OnPropertyChanged("TEST1");
}
}
}
private string test2 = string.Empty;
public string TEST2
{
get
{
return test2;
}
set
{
//test2 값이 변경되었을 때, TEST2 속성 변경 이벤트 발생
if (test2 != value)
{
test2 = value;
OnPropertyChanged("TEST2");
}
}
}
private string test3 = string.Empty;
public string TEST3
{
get
{
return test3;
}
set
{
//test3 값이 변경되었을 때, TEST3 속성 변경 이벤트 발생
if (test3 != value)
{
test3 = value;
OnPropertyChanged("TEST3");
}
}
}
private string test4 = string.Empty;
public string TEST4
{
get
{
return test4;
}
set
{
//test4 값이 변경되었을 때, TEST4 속성 변경 이벤트 발생
if (test4 != value)
{
test4 = value;
OnPropertyChanged("TEST4");
}
}
}
//속성 값이 변경되었을 때, PropertyChanged 이벤트를 발생시킴
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
lock (syncIns)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
}
실행 프로그램
간단하게 바인딩이 적용되는 예제를 만들어 보았습니다.
많은 도움이 되길 바랍니다.
감사합니다.
'WPF' 카테고리의 다른 글
[WPF] - 리소스 적용하기 (0) | 2023.01.03 |
---|---|
[WPF] - Border (0) | 2022.12.31 |
[WPF] - Style, ControlTemplate (0) | 2022.12.31 |
[WPF] - ResourceDictionary 사용 (0) | 2022.12.30 |
[WPF] - 프로젝트 생성 및 시작 (0) | 2022.12.28 |