์ด ๋ฆฌํฌ์งํ ๋ฆฌ๋ WPF Xaml Binding ๊ฐ๋ ๊ณผ ๊ธฐ์ ์ ํ์ฉํ๋๋ฐ ํ์ํ ์ค๋ช ์ ๋ค๋ฃจ๋ Article์ ๋๋ค.
Star | License | Activity |
---|---|---|
DataContext๋ FrameworkElement์ ํฌํจ๋ ์์ฑ์
๋๋ค.
PresentationFramework.dll
namespace System.Windows
{
public class FrameworkElement : UIElement
{
public static readonly DependencyProperty DataContextProperty;
public object DataContext { get; set; }
}
}
๊ทธ๋ฆฌ๊ณ WPF์ ๋ชจ๋ UI ์ปจํธ๋กค์ FrameworkElement
ํด๋์ค๋ฅผ ์์ํฉ๋๋ค.
๋ฐ์ธ๋ฉ ๋๋ ๋ฐ์ดํฐ ์ปจํ ์คํธ๋ฅผ ๋ฐฐ์๊ฐ๋ ์์ ์์ FrameworkElement๋ฅผ ๋ ๊น์ด ์ฐ๊ตฌํ ํ์๊ฐ ์์ต๋๋ค. ํ์ง๋ง ๋ชจ๋ UI ์ปจํธ๋กค์ ํฌํจํ ์ ์๋ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ฐ์ฒด๊ฐ FrameworkElement๋ผ๋ ์ฌ์ค์ ๊ฐ๋จํ ์ธ๊ธํ๊ธฐ ์ํจ์ ๋๋ค.
Binding can directly recall values for the DataContext type format starting with the nearest DataContext.
<TextBlock Text="{Binding}" DataContext="James"/>
Text="{Binding}
์ ๋ฐ์ธ๋ฉ๋ ๊ฐ์ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฐ์ดํฐ ์ปจํ
์คํธ์ธ TextBlock
์์ ์ง์ ์ ๋ฌ๋ฉ๋๋ค.
๋ฐ๋ผ์ Text
์ ๋ฐ์ธ๋ฉ ๊ฒฐ๊ณผ ๊ฐ์ 'James'์
๋๋ค.
-
Type integer
Xaml์์ DataContext์ ์ง์ ๊ฐ์ ํ ๋นํ๋ ๊ฒฝ์ฐ ์ ์ ๋ฐ ๋ถ์ธ๊ณผ ๊ฐ์ ๊ฐ ์ ํ์ ๋ํด ๋จผ์ ๋ฆฌ์์ค ์ ์๊ฐ ํ์ํฉ๋๋ค. ์๋ํ๋ฉด ๋ชจ๋ ๋ฌธ์์ด์ด ๋ฌธ์์ด๋ก ์ธ์๋๊ธฐ ๋๋ฌธ์ ๋๋ค.Simple type variable type is not supported by standard.
์ด๋ค ๋จ์ด๋ก๋ ์ ์ํ ์ ์์ง๋ง ๋๋ถ๋ถsys
๋จ์ด๋ฅผ ์ฌ์ฉํฉ๋๋ค.xmlns:sys="clr-namespace:System;assembly=mscorlib"
StaticResource ํ์์ผ๋ก ์์ฑํ ์ ํ์ ๊ฐ์ ์ ์ธํฉ๋๋ค.
<Window.Resources> <sys:Int32 x:Key="YEAR">2020</sys:Int32> </Window.Resources> ... <TextBlock Text="{Binding}" DataContext="{StaticResource YEAR"/>
-
All type of value
๊ฐ์ด ๋ฐ์ดํฐ ์ปจํ ์คํธ์ ์ง์ ๋ฐ์ธ๋ฉ๋๋ ๊ฒฝ์ฐ๋ ๊ฑฐ์ ์์ต๋๋ค.
Because we're going to bind an object.<Window.Resources> <sys:Boolean x:Key="IsEnabled">true</sys:Boolean> <sys:double x:Key="Price">7.77</sys:double> </Window.Resources> ... <StackPanel> <TextBlock Text="{Binding}" DataContext="{StaticResource IsEnabled}"/> <TextBlock Text="{Binding}" DataContext="{StaticResource Price}"/> </StackPanel>
-
Another type
์คํธ๋ง๋ฟ๋ง ์๋๋ผ ๋ค์ํ ํ์ ์ด ๊ฐ๋ฅํฉ๋๋ค. ๋ฐ์ดํฐ ์ปจํ ์คํธ๊ฐ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
WPF์์ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ ๋, ๋๋ถ๋ถ์ ๊ฐ๋ฐ์๋ค์ DataContext์ ๊ธฐ๋ฅ ๋ฐ ์ค์์ฑ์ ๋ํด ์์ ํ ์์ง ๋ชปํฉ๋๋ค. ํนํ ๋๊ท๋ชจ WPF ํ๋ก์ ํธ๋ฅผ ๋ด๋นํ๊ฑฐ๋ ์ฐธ์ฌํ๋ ๊ฒฝ์ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ DataContext ๊ณ์ธต์ ๋ณด๋ค ๋ช ํํ๊ฒ ์ดํดํด์ผ ํฉ๋๋ค. DataContext ๊ฐ๋ ์ด ์์ผ๋ฉด ๊ธฐ๋ฅ์ ์์ ๋กญ๊ฒ ๊ตฌํํ๋ ๋ฐ ํ๊ณ๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
- DataContext Binding
- Element Binding
- MultiBinding
- Self Property Binding
- Find Ancestor Binding
- TemplatedParent Binding
- Static Property Binding
string property
<TextBox Text="{Binding Keywords}"/>
<CheckBox x:Name="usingEmail"/>
<TextBlock Text="{Binding ElementName=usingEmail, Path=IsChecked}"/>
<TextBlock Margin="5,2" Text="This disappears as the control gets focus...">
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource TextInputToVisibilityConverter}">
<Binding ElementName="txtUserEntry2" Path="Text.IsEmpty" />
<Binding ElementName="txtUserEntry2" Path="IsFocused" />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
<TextBlock x:Name="txt" Text="{Binding ElementName=txt, Path=Tag}"/>
์์ ์ ์์ฑ์ ๋ฐ์ธ๋ฉํด์ผ ํ๋ ๊ฒฝ์ฐ ์์ ๋ฐ์ธ๋ฉ ๋์ Element Binding
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์์ ์ ์์ฑ์ ๋ฐ์ธ๋ฉํ๊ธฐ ์ํด x:Name
์ ์ ์ธํ ํ์๊ฐ ์์ต๋๋ค.
<TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=Tag}"/>
๊ฐ์ฅ ๊ฐ๊น์ด ์์ ์ปจํธ๋กค์ ๊ธฐ์ค์ผ๋ก ๊ฐ์ ธ์ต๋๋ค.
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"/>
Trigger
์์ ์์ ๊ฐ์ฒด์ ์์ฑ์ ์ก์ธ์คํ ๋ ์ ์ฉํฉ๋๋ค.
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=IsSelected}" Value="True">
<Setter Property="Background" Value="#DDDDDD"/>
</DataTrigger>
DataContext ๊ฐ์ฒด๊ฐ ์๋ ๊ฒฝ์ฐ ํด๋น ์์ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ DataContext
(ViewModel)์ ๋ํ ์ ๊ทผ์ ๊ฐ๊ธ์ ํผํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.Email}"/>
ํ์ฌ ๋ฐ์ธ๋ฉ๋ DataContext
๊ฐ ์๋ ๋ค๋ฅธ DataContext
๋ฅผ ๋ฐ์ธ๋ฉํ๋ ค๋ ๊ฒฝ์ฐ ๋ค์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
public partial class A : UserControl
{
public A()
{
InitializeComponent();
DataContext = new MainViewModel();
}
public class MainViewModel
{
public B G1VM { get; set; } = new B();
public C G2VM { get; set; } = new C();
}
}
<TabControl DataContext="{Binding G1VM}">
<TabItem Header="TMP">
<DataGrid ItemsSource="{Binding datagrid}"
DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.G1VM}"/>
<!--It can also be expressed as follows.-->
<!--<DataGrid ItemsSource="{Binding datagrid}"
DataContext="{Binding Parent.G2VM}"/>-->
</TabItem>
</TabControl>
ControlTemplate
๋ด์์ ์ฌ์ฉํ ์ ์๋ ๋ฉ์๋๋ก ControlTemplate
์ ์์ ์ ์์ฑ์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
๋ชจ๋ ์์ฑ ๋ฐ ๋ฐ์ดํฐ ์ปจํ ์คํธ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"/>
๋ฐ์ธ๋ฉ ์์ฑ ๊ฐ์ ์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค.
namespace Exam
{
public class ExamClass
{
public static string ExamText { get; set; }
}
}
<Window ... xmlns:exam="clr-namespace:Exam">
<TextBlock Text="{Binding exam:ExamClass.ExamText}"/>
๋๋ Converter
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ฒ๋ผ ๋ฆฌ์์ค ํค๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
<Window.Resource>
<cvt:VisibilityToBooleanConverter x:Key="VisibilityToBooleanConverter"/>
<exam:ExamClass x:Key="ExamClass">
</Window.Resource>
...
<TextBlock Text="{Binding Source={StaticResource ExamClass}, Path=ExamText}"/>
โ๏ธ ๋ฐ์ธ๋ฉํ ์์ฑ์ด DataContext์ ํฌํจ๋ ๊ฒฝ์ฐ ElementBinding์ ์ฌ์ฉํ ํ์๊ฐ ์์ต๋๋ค.
DataContext์ ํฌํจ๋ ์์ฑ์ ํด๋ํด ElementBinding์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ธฐ๋ฅ์ ์ผ๋ก ๋ฌธ์ ๊ฐ ์์ง๋ง, ๋ฐ์ธ๋ฉ์ ๊ธฐ๋ณธ ํจํด์ ๊นฐ ์ ์์ต๋๋ค.
<TextBox x:Name="text" Text="{Binding UserName}"/>
...
<TextBlock Text="{Binding ElementName=text, Path=Text}"/>
<TextBox Text="{Binding UserName}"/>
...
<TextBlock Text="{Binding UserName}"/>
<Window x:Name="win">
<TextBlock Text="{Binding ElementName=win, Path=DataContext.UserName}"/>
...
<Window>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.UserName}"/>
...
<Window>
<TextBlock DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext}"
Text="{Binding UserName}"/>
...
<TextBlock x:Name="txt" Text="{Binding ElementName=txt, Path=Foreground}"/>
<TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=Foreground}"/>
๐ StackOverflow ย How do I use WPF bindings with RelativeSource?