Data Binding-① : 데이터 바인딩 기초 및 데이터 컨텍스트 속성 사용
원본은 위의 링크를 참고해주세요!
WPF는 흔히들 말하는 디자인 패턴중에서 MVVM 패턴으로 프로젝트 코드를 구현하는것이 가장 효율적이라고 합니다.
물론 작은 규모의 프로젝트나 개인적인 프로젝트라면 굳이 MVVM 구조를 고집하지 않아도 될것이라 생각합니다. 왜냐하면? MVVM의 최대 장점은 View와 ViewModel간의 의존성을 최소화해서 실무적으로 봤을때 협업하기에도 편하고 추후 유지보수시에 코드를 수정하기에도 편하다는 장점을 가지고 있기 때문입니다.
(MVVM에 대한 자료와 정보는 인터넷에 많으니 별도로 참고 하는게 더 이득!!)
어쨋든 사설이 길었지만 이번글은 MVVM 패턴에서 빼놓을 수 없는.. WPF에서 빼놓을 수 없는..
개념인 데이터 바인딩(Data Binding)과 데이터 컨텍스트(Data Context) 속성을 사용해서 간단한 바인딩을 해보도록 하겠습니다.
1. 데이터 바인딩(Data Binding) 기초
1️⃣ 데이터 바인딩에 대한 기본 개념
✅ 데이터 바인딩이란?
→ 유저 인터페이스(View)와 비즈니스 모델(ViewModel) 사이에 자동으로 데이터를 업데이트 해주는 방법
✅ 흔히 일반적으로(닷넷 프로퍼티)는 INotifyPropertyChanged 인터페이스에서 PropertyChanged 이벤트를 통해 데이터가 바인딩 되는 시기를 알려준다.
→ 이번에는 바인딩에 대한 기본적인 개념만 이해하기위해 이벤트를 사용하지 않고 xaml파일 내에서만 바인딩을 수행해볼 예정입니다.😊
2️⃣ 데이터 바인딩 관련 기초 실습 : TextBox에 입력된 값을 반영하는 Label간의 간단한 바인딩
① 본문에서 사용한 Code
<StackPanel>
<TextBox x:Name="txtInput" />
<Label Content="{Binding Text, ElementName=txtInput,
UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
본문에서는 TextBox의 이름을 txtInput으로 정의하였고, Label의 Content 속성을 TextBox(txtInput)의 Text 속성과 바인딩 하였고, 프로퍼티가 변경될때만 업데이트 되도록 트리거(Trigger)를 설정하였습니다.
저도 이를 인용해서 텍스트 박스를 한개 더 추가해서 Label의 Background를 TextBox의 Text 속성과 바인딩하여 색상을 변경해보도록 하겠습니다.
② 응용 예제 Code
TextBox의 이름이 Label의 어떠한 속성에 각각 바인딩이 되는지 표시하기 위해서 코드부분을 캡쳐하였습니다.
✅ 첫번째 TextBox의 Text는 Label의 Content 속성과 Binding
✅ 두번째 TextBox의 Text는 Label의 Background 속성과 Binding
(사실 CheckBox를 추가해서 체크 하면 Label은 Hidden 하게끔 할려고 했는데, 이는 ValueConverter의 개념을 추가해야하기 때문에 변경하였습니다.. 😂)
어짜피 실제 실무에서는 이렇게 xaml파일 내에서 바인딩을 하는 경우는 크게 없을것이라 생각합니다. 위의 코드는 오로지 기초 참고용으로만 봐주시면 좋을 것 같습니다. (함께 공부합시다!!)
③ 응용 예제 결과
Label에 있는 Content 속성과 Background속성에 대한 속성 값이 TextBox의 Text와 바인딩이 되어서 프로퍼티가 변경될때 Label의 속성이 Update됨을 알 수 있다.
2. 데이터 컨텍스트(Data Context) 속성을 사용해서 바인딩
1️⃣ 데이터 컨텍스트(Data Context)란?
✅ FrameworkElement에서 파생되는 모든 WPF 컨트롤에는 DataContext 속성이 있습니다.
✅ DataContext는 같은 오브젝트에 여러개의 속성을 바인딩할 경우 위와 같이 일일히 ElementName을 설정해서 바인딩하기 번거로우니 사용되는 속성입니다.
→ 즉, DataContext는 계층구조를 통해 상속되고 자식 컨트롤에 값을 바인딩 할 수 있도록 해줍니다.
2️⃣ 데이터 컨텍스트 속성을 사용한 바인딩 실습
① MyCustomer.cs
internal class MyCustomer
{
private string firstName = string.Empty;
private string lastName = string.Empty;
private string street = string.Empty;
private string city = string.Empty;
public MyCustomer()
{
FirstName = "아이스";
LastName = "아메리카노";
City = "강릉시";
Street = "안목해변로";
}
public string FirstName { get => firstName; set => firstName = value; }
public string LastName { get => lastName; set => lastName = value; }
public string Street { get => street; set => street = value; }
public string City { get => city; set => city = value; }
}
MainWindow.xaml에 있는 4개의 TextBox의 Text 속성 값이 될 프로퍼티를 저장하고 있는 Class
② MainWindow.xaml
<Grid>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="FirstName : "
Width="70" />
<TextBox Text="{Binding FirstName}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="LastName : "
Width="70" />
<TextBox Text="{Binding LastName}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Street : "
Width="70" />
<TextBox Text="{Binding Street}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="City : "
Width="70" />
<TextBox Text="{Binding City}" />
</StackPanel>
</StackPanel>
</Grid>
각각의 TextBox의 Text 속성에 대한 속성값들이 MyCustomer.cs의 변수와 1:1로 바인딩 되어있습니다.
이렇게만 구성하면 끝나는 것이 아니라 최종적으로 DataContext를 MyCustomer로 설정해주는 과정이 남아있습니다.
데이터 컨텍스트를 설정하는 방법은 여러가지가 있는데 대표적(?)으로 사용되는 4가지를 정리하였습니다.
3️⃣ 데이터 컨텍스트를 설정하는 4가지 방법
① MainWindow.xaml.cs 에서 DataContex 설정하기
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MyCustomer my = new MyCustomer();
this.DataContext = my;
}
}
데이터 바인딩에 연결된 프로퍼티들을 보관하는 클래스를 인스턴스화 하여 DataContext에 설정하는 과정입니다.
이는 본 MainWindow에서 사용하는 모든 컨트롤에서 바인딩하는데 사용될 수 있습니다.
② Window 태그의 DataContext 속성에서 Local에 Class 설정하기
<Window x:Class="WpfTutorial.MainWindow"
xmlns:local="clr-namespace:WpfTutorial"
... 중략 ...
<Window.DataContext>
<local:MyCustomer />
</Window.DataContext>
<Grid>
... 중략 ...
Window.DataContext에 설정하면 1번 방법과 유사하게 전역적으로 설정했다고 볼 수 있습니다.
여기서 local은 위의 코드에서 알 수 있다시피 WpfTutorial이라는 프로젝트를 의미합니다.
③ 특정 Control에 대해서만 DataContext 설정하기
<Grid>
<StackPanel Orientation="Vertical">
<StackPanel.DataContext>
<local:MyCustomer />
</StackPanel.DataContext>
<StackPanel Orientation="Horizontal">
<Label Content="FirstName : "
Width="70" />
<TextBox Text="{Binding FirstName}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="LastName : "
Width="70" />
<TextBox Text="{Binding LastName}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Street : "
Width="70" />
<TextBox Text="{Binding Street}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="City : "
Width="70" />
<TextBox Text="{Binding City}" />
</StackPanel>
</StackPanel>
</Grid>
DataContext는 계층구조를 통해 상속되고 자식 컨트롤에 값을 바인딩할 수 있다고 하였습니다.
위와 같은 구조는 StackPanel이라는 부모 컨트롤에 상속이 되어서 그 자식 컨트롤인 TextBox에 값을 바인딩하였습니다.
④ StaticResource를 사용해서 정의하고 해당 Resource를 Key값을 통해 DataContext 설정
<Window.Resources>
<local:MyCustomer x:Key="MyCutomerKey" />
</Window.Resources>
<Window.DataContext>
<StaticResource ResourceKey="MyCutomerKey" />
</Window.DataContext>
Resource라는 개념이 추가되었습니다. 사실 저도 아직 잘 모르겠습니다.😂
리소스에서 DynamicResource가 있고 StaticResource가 있는데 이에 대해서는 조금 더 공부하고 정리해보록 하겠습니다.
하여튼 Window.Resources속성에 DataContext에 사용할 값을 저장하고 Key값을 통해 전역적으로 불러오는 개념으로 생각이 됩니다.
개인적으로는 1번이나 2번 과정이 조금 더 깔끔하고 많이 사용될 것이라 생각 됩니다..😊
댓글