[WPF] DataContext(데이터 컨텍스트)

[WPF] DataContext(데이터 컨텍스트)

이번 글에서는 데이터 컨텍스트(DataContext)에 대해 알아보겠습니다.
WPF에서 데이터 바인딩과 엮여서 많이 사용되는 개념 중 하나가 DataContext입니다. Data Binding을 하다보면 Binding 속성이 안되거나 제대로 동작이 되지 않을 때가 있습니다. 그럴 때 보통 DataContext 설정이 문제입니다.

DataContext를 간단히 말하면, Data Binding를 위해 소스 객체를 지정하는 것을 말합니다. xaml 요소가 데이터를 어디에서 가져올지 알려주는 기준 역할을 한다고 이해하시면 됩니다. 사용 하는 방법은 간단합니다.

DataContext 예시 – XAML

xaml에서 DataContext를 사용하는 방법은 간단합니다. 아래는 Human이란 객체를 선언해주고 Window 태그에서 DataContext를 사용하는 방법입니다.

public class Human
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Human()
    {
        Name = "";
        Age = 0;
    }
}
<Window x:Class="WpfApp2.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:WpfApp2"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:Human/>
    </Window.DataContext>
    <StackPanel>
        <TextBlock Text="{Binding Name}"/>
        <TextBlock Text="{Binding Age}"/>
    </StackPanel>
</Window>

이렇게 상위 요소에서 DataContext를 사용하면 하위 요소에서도 사용 가능합니다. 반대로 말하면 하위 요소에서 사용하면 상위 요소에서는 사용하지 못한다는 의미입니다.

<Window x:Class="WpfApp2.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:WpfApp2"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <StackPanel.DataContext>
            <local:Human/>
        </StackPanel.DataContext>
        <TextBlock Text="{Binding Name}"/>
        <TextBlock Text="{Binding Age}"/>
    </StackPanel>
    <TextBlock Text="{Binding Name}"/>
    <TextBlock Text="{Binding Age}"/>
</Window>

StackPanel에서 DataContext를 사용하면 StackPanel 요소 밖에서는 사용이 불가합니다.

DataContext 예시 – 코드 비하인드

xaml에서 하는 방법 외에도 코드 비하인드단에서 DataContext를 지정하는 방법도 있습니다.

namespace WpfApp2
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Human human = new Human();
            this.DataContext = human;
        }
    }
}

Windows에 설정하지 않고 StackPanel에 설정하고 싶으면 StackPanel 요소에 이름을 지정해준 뒤 코드 비하인드 단에서 설정해주는 방법도 있습니다.

<Window x:Class="WpfApp2.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:WpfApp2"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel x:Name="stackpanel">
        <TextBlock Text="{Binding Name}"/>
        <TextBlock Text="{Binding Age}"/>
    </StackPanel>
</Window>
namespace WpfApp2
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Human human = new Human();
            stackpanel.DataContext = human;
        }
    }
}

이렇게 코드 비하인드 단에서 지정해주면 xaml 파일에서는 Binding할 소스 객체를 알 수 없어 찾을 수 없다는 밑줄 표시가 발생할 수 있습니다. 하지만 빌드를 하면 잘 성공하는 것을 볼 수 있습니다.


github : https://github.com/3001ssw/c_sharp/tree/main/WPF/Simple_WfpApp/WpfApp2