{"id":13399273,"url":"https://github.com/jamesnet214/wpf-xaml-binding","last_synced_at":"2025-04-10T02:01:50.460Z","repository":{"id":127733705,"uuid":"312139412","full_name":"jamesnet214/wpf-xaml-binding","owner":"jamesnet214","description":null,"archived":false,"fork":false,"pushed_at":"2022-07-03T13:42:53.000Z","size":128,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-08-10T03:01:18.835Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jamesnet214.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-11-12T01:53:17.000Z","updated_at":"2024-08-10T03:01:18.836Z","dependencies_parsed_at":"2023-03-25T13:02:40.270Z","dependency_job_id":null,"html_url":"https://github.com/jamesnet214/wpf-xaml-binding","commit_stats":null,"previous_names":["jameslee214/wpf-xaml-binding"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesnet214%2Fwpf-xaml-binding","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesnet214%2Fwpf-xaml-binding/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesnet214%2Fwpf-xaml-binding/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesnet214%2Fwpf-xaml-binding/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamesnet214","download_url":"https://codeload.github.com/jamesnet214/wpf-xaml-binding/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248142967,"owners_count":21054671,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T19:00:35.881Z","updated_at":"2025-04-10T02:01:50.383Z","avatar_url":"https://github.com/jamesnet214.png","language":null,"funding_links":[],"categories":["WPF Lecture"],"sub_categories":[],"readme":"## Xaml Binding\n  \n이 리포지토리는 WPF Xaml Binding 개념과 기술을 활용하는데 필요한 설명을 다루는 Article입니다.\n\n\u003ca href=\"https://github.com/devncore/devncore\"\u003e\u003cstrong\u003e더 알아보기 »\u003c/strong\u003e\u003c/a\u003e\n  \n| Star | License | Activity |\n|:----:|:-------:|:--------:|\n| \u003ca href=\"https://github.com/devncore/wpf-xaml-binding/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/devncore/wpf-xaml-binding\" alt=\"Github Stars\"\u003e\u003c/a\u003e | \u003cimg src=\"https://img.shields.io/github/license/devncore/wpf-xaml-binding\" alt=\"License\"\u003e | \u003ca href=\"https://github.com/devncore/wpf-xaml-binding/pulse\"\u003e\u003cimg src=\"https://img.shields.io/github/commit-activity/m/devncore/wpf-xaml-binding\" alt=\"Commits-per-month\"\u003e\u003c/a\u003e |\n\n\u003cbr /\u003e\n\n## DataContext\n\n__DataContext는 FrameworkElement에 포함된 속성입니다.__  \n`PresentationFramework.dll`\n\n```csharp\nnamespace System.Windows\n{\n    public class FrameworkElement : UIElement\n    {\n        public static readonly DependencyProperty DataContextProperty;\n        public object DataContext { get; set; }\n    }\n}\n```\n\n그리고 WPF의 모든 UI 컨트롤은 `FrameworkElement` 클래스를 상속합니다. \n\u003e 바인딩 또는 데이터 컨텍스트를 배워가는 시점에서 FrameworkElement를 더 깊이 연구할 필요가 없습니다.\n\u003e 하지만 모든 UI 컨트롤을 포함할 수 있는 가장 가까운 개체가 FrameworkElement라는 사실을 간단히 언급하기 위함입니다.\n\u003cbr /\u003e\n\n### _DataContext is always the reference point for Binding._ \nBinding can directly recall values for the DataContext type format starting with the nearest DataContext.\n```xaml\n\u003cTextBlock Text=\"{Binding}\" DataContext=\"James\"/\u003e\n```\n`Text=\"{Binding}`에 바인딩된 값은 가장 가까운 데이터 컨텍스트인 `TextBlock`에서 직접 전달됩니다.    \n따라서 `Text`의 바인딩 결과 값은 'James'입니다.\n\u003cbr /\u003e\n\n- __Type integer__  \nXaml에서 DataContext에 직접 값을 할당하는 경우 정수 및 부울과 같은 값 유형에 대해 먼저 리소스 정의가 필요합니다.\n왜냐하면 모든 문자열이 문자열로 인식되기 때문입니다.\n\n    #### 1. Xaml에서 System `mscrollib` 사용\n    \u003e Simple type variable type is not supported by standard.  \n    \u003e 어떤 단어로도 정의할 수 있지만 대부분 `sys` 단어를 사용합니다.\n    ```xaml\n    xmlns:sys=\"clr-namespace:System;assembly=mscorlib\"\n    ```\n\n    #### 2. xaml에서 `YEAR` 리소스 키 생성\n    \u003e StaticResource 형식으로 생성할 유형의 값을 선언합니다.\n    ```xaml\n    \u003cWindow.Resources\u003e\n        \u003csys:Int32 x:Key=\"YEAR\"\u003e2020\u003c/sys:Int32\u003e\n    \u003c/Window.Resources\u003e\n    ...\n    \u003cTextBlock Text=\"{Binding}\" DataContext=\"{StaticResource YEAR\"/\u003e\n    ```\n\n- __All type of value__  \n값이 데이터 컨텍스트에 직접 바인딩되는 경우는 거의 없습니다.    \nBecause we're going to bind an object.\n    ```xaml\n    \u003cWindow.Resources\u003e\n        \u003csys:Boolean x:Key=\"IsEnabled\"\u003etrue\u003c/sys:Boolean\u003e\n        \u003csys:double x:Key=\"Price\"\u003e7.77\u003c/sys:double\u003e\n    \u003c/Window.Resources\u003e\n    ...\n    \u003cStackPanel\u003e\n        \u003cTextBlock Text=\"{Binding}\" DataContext=\"{StaticResource IsEnabled}\"/\u003e\n        \u003cTextBlock Text=\"{Binding}\" DataContext=\"{StaticResource Price}\"/\u003e\n    \u003c/StackPanel\u003e\n    ```\n\n- __Another type__  \n스트링뿐만 아니라 다양한 타입이 가능합니다. 데이터 컨텍스트가 객체이기 때문입니다.\n\u003cbr /\u003e\n\nWPF에서 바인딩을 사용할 때, 대부분의 개발자들은 DataContext의 기능 및 중요성에 대해 완전히 알지 못합니다. 특히 대규모 WPF 프로젝트를 담당하거나 참여하는 경우 애플리케이션의 DataContext 계층을 보다 명확하게 이해해야 합니다. DataContext 개념이 없으면 기능을 자유롭게 구현하는 데 한계가 있기 때문입니다.\n\n\u003cbr\u003e\n\n* * *  \n\n## Binding\n\n- [DataContext Binding](#datacontext-binding)\n- [Element Binding](#element-binding)\n- [MultiBinding](#multibinding)\n- [Self Property Binding](#self-property-binding)\n- [Find Ancestor Binding](#find-ancestor-binding)\n- [TemplatedParent Binding](#templatedparent-binding)\n- [Static Property Binding](#static-property-binding)  \n\u003cbr /\u003e\n\n### DataContext Binding\n\n`string property`\n```xaml\n\u003cTextBox Text=\"{Binding Keywords}\"/\u003e\n```\n\u003cbr /\u003e\n\n### Element Binding\n\n```xaml\n\u003cCheckBox x:Name=\"usingEmail\"/\u003e\n\u003cTextBlock Text=\"{Binding ElementName=usingEmail, Path=IsChecked}\"/\u003e\n```\n\u003cbr /\u003e\n\n### MultiBinding\n\n```xaml\n\u003cTextBlock Margin=\"5,2\" Text=\"This disappears as the control gets focus...\"\u003e\n  \u003cTextBlock.Visibility\u003e\n      \u003cMultiBinding Converter=\"{StaticResource TextInputToVisibilityConverter}\"\u003e\n          \u003cBinding ElementName=\"txtUserEntry2\" Path=\"Text.IsEmpty\" /\u003e\n          \u003cBinding ElementName=\"txtUserEntry2\" Path=\"IsFocused\" /\u003e\n      \u003c/MultiBinding\u003e\n  \u003c/TextBlock.Visibility\u003e\n\u003c/TextBlock\u003e\n```\n\u003cbr /\u003e\n \n### Self Property Binding\n\n```xaml\n\u003cTextBlock x:Name=\"txt\" Text=\"{Binding ElementName=txt, Path=Tag}\"/\u003e\n```\n자신의 속성을 바인딩해야 하는 경우 요소 바인딩 대신 `Element Binding`을 사용할 수 있습니다.    \n자신의 속성을 바인딩하기 위해 `x:Name`을 선언할 필요가 없습니다.\n\n```xaml\n\u003cTextBlock Text=\"{Binding RelativeSource={RelativeSource Self}, Path=Tag}\"/\u003e\n```\n\u003cbr /\u003e\n \n### Find Ancestor Binding\n\n가장 가까운 상위 컨트롤을 기준으로 가져옵니다.\n\n```xaml\n\u003cTextBlock Text=\"{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}\"/\u003e\n```\n\u003cbr /\u003e\n\n`Trigger`에서 상위 개체의 속성에 액세스할 때 유용합니다.\n```xaml\n\u003cDataTrigger Binding=\"{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=IsSelected}\" Value=\"True\"\u003e\n    \u003cSetter Property=\"Background\" Value=\"#DDDDDD\"/\u003e\n\u003c/DataTrigger\u003e\n```\n\u003cbr /\u003e\n\nDataContext 객체가 있는 경우 해당 속성을 사용할 수 있습니다.    \n그러나 `DataContext`(ViewModel)에 대한 접근은 가급적 피하는 것이 좋습니다.\n```xaml\n\u003cTextBlock Text=\"{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.Email}\"/\u003e\n```\n\u003cbr /\u003e\n\n현재 바인딩된 `DataContext`가 아닌 다른 `DataContext`를 바인딩하려는 경우 다음 방법을 사용할 수 있습니다.\n```csharp\npublic partial class A : UserControl\n{\n    public A()\n    {\n        InitializeComponent();\n        DataContext = new MainViewModel();\n    }\n    \n    public class MainViewModel\n    {\n        public B G1VM { get; set; } = new B();\n        public C G2VM { get; set; } = new C();\n    }\n}\n```\n\n```xaml\n\u003cTabControl DataContext=\"{Binding G1VM}\"\u003e\n  \u003cTabItem Header=\"TMP\"\u003e\n    \u003cDataGrid ItemsSource=\"{Binding datagrid}\" \n              DataContext=\"{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.G1VM}\"/\u003e\n    \u003c!--It can also be expressed as follows.--\u003e\n    \u003c!--\u003cDataGrid ItemsSource=\"{Binding datagrid}\" \n                  DataContext=\"{Binding Parent.G2VM}\"/\u003e--\u003e\n  \u003c/TabItem\u003e\n\u003c/TabControl\u003e\n```\n\u003cbr /\u003e\n\n### TemplatedParent Binding\n\n`ControlTemplate` 내에서 사용할 수 있는 메서드로 `ControlTemplate`의 자신의 속성을 가져올 수 있습니다.\n\n```xaml\n\u003cStyle TargetType=\"Button\"\u003e\n  \u003cSetter Property=\"Template\"\u003e\n      \u003cSetter.Value\u003e\n          \u003cControlTemplate TargetType=\"Button\"\u003e\n              \u003cTextBlock Text=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}\"/\u003e\n          \u003c/ControlTemplate\u003e\n      \u003c/Setter.Value\u003e\n  \u003c/Setter\u003e\n\u003c/Style\u003e\n```\n\n모든 속성 및 데이터 컨텍스트에 접근할 수 있습니다.\n\n```xaml\n\u003cTextBlock Text=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}\"/\u003e\n```\n\u003cbr /\u003e\n\n### Static Property Binding\n\n바인딩 속성 값에 직접 접근할 수 있습니다.    \n\n#### 1. `static` 속성을 선언합니다.\n\n```csharp\nnamespace Exam\n{\n  public class ExamClass\n  {\n      public static string ExamText { get; set; }\n  }\n} \n```\n\n#### 2. XAML에서 정적 클래스를 사용합니다.\n\n```xaml\n\u003cWindow ... xmlns:exam=\"clr-namespace:Exam\"\u003e\n```\n\n#### 3. Binding property.\n\n```xaml\n\u003cTextBlock Text=\"{Binding exam:ExamClass.ExamText}\"/\u003e\n```\n\n_또는 `Converter`를 사용하는 것처럼 리소스 키를 설정할 수 있습니다._  \n\n```xaml\n\u003cWindow.Resource\u003e\n  \u003ccvt:VisibilityToBooleanConverter x:Key=\"VisibilityToBooleanConverter\"/\u003e\n  \u003cexam:ExamClass x:Key=\"ExamClass\"\u003e\n\u003c/Window.Resource\u003e\n...\n\n\u003cTextBlock Text=\"{Binding Source={StaticResource ExamClass}, Path=ExamText}\"/\u003e\n```\n\n\u003cbr /\u003e\n\n* * *  \n\n## Bad Binding \u0026 Good Binding \n\n#### :heavy_check_mark: 바인딩할 속성이 DataContext에 포함된 경우 ElementBinding을 사용할 필요가 없습니다.\nDataContext에 포함된 속성에 해대해 ElementBinding을 사용하는 것은 기능적으로 문제가 없지만, 바인딩의 기본 패턴을 깰 수 있습니다.\n\n#### :slightly_frowning_face: Bad Binding \n\n```xaml\n\u003cTextBox x:Name=\"text\" Text=\"{Binding UserName}\"/\u003e\n...\n\u003cTextBlock Text=\"{Binding ElementName=text, Path=Text}\"/\u003e\n```\n   \n#### :grinning: Good Binding\n\n```xaml\n\u003cTextBox Text=\"{Binding UserName}\"/\u003e\n...\n\u003cTextBlock Text=\"{Binding UserName}\"/\u003e\n```\n\n\u003cbr /\u003e\n\n#### :heavy_check_mark: 상위 컨트롤의 속성을 사용할 때는 ElementBinding을 사용하지 마세요.    \n\n#### :slightly_frowning_face: Bad Binding \n\n```xaml\n\u003cWindow x:Name=\"win\"\u003e\n  \u003cTextBlock Text=\"{Binding ElementName=win, Path=DataContext.UserName}\"/\u003e\n  ...\n```\n    \n#### :grinning: Good Binding\n\n```xaml\n\u003cWindow\u003e\n  \u003cTextBlock Text=\"{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.UserName}\"/\u003e\n  ...\n```      \n\n#### :laughing: Great!\n\n```xaml\n\u003cWindow\u003e\n  \u003cTextBlock DataContext=\"{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext}\" \n             Text=\"{Binding UserName}\"/\u003e\n  ...\n```\n\u003cbr /\u003e\n\n#### :heavy_check_mark: 자기 자신의 속성을 사용할 때 ElementBinding을 사용하지 마세요.    \n\n#### :slightly_frowning_face: Bad Binding \n\n```xaml\n\u003cTextBlock x:Name=\"txt\" Text=\"{Binding ElementName=txt, Path=Foreground}\"/\u003e\n```\n\n#### :grinning: Good Binding\n\n```xaml\n\u003cTextBlock Text=\"{Binding RelativeSource={RelativeSource Self}, Path=Foreground}\"/\u003e\n```\n\n\u003cbr\u003e\n\n## Reference\n[:bookmark_tabs:](https://stackoverflow.com/questions/84278/how-do-i-use-wpf-bindings-with-relativesource) **StackOverflow** \u0026nbsp; \u003cins\u003eHow do I use WPF bindings with RelativeSource?\u003c/ins\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamesnet214%2Fwpf-xaml-binding","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamesnet214%2Fwpf-xaml-binding","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamesnet214%2Fwpf-xaml-binding/lists"}