{"id":42921,"date":"2024-11-13T22:28:14","date_gmt":"2024-11-13T22:28:14","guid":{"rendered":"https:\/\/atmokpo.com\/w\/?p=42921"},"modified":"2024-11-26T06:34:27","modified_gmt":"2024-11-26T06:34:27","slug":"mvvm-2-%ec%bb%a4%eb%a7%a8%eb%93%9c%ec%99%80-%eb%b0%94%ec%9d%b8%eb%94%a9-%ea%b3%a0%ea%b8%89-%ed%99%9c%ec%9a%a9-%eb%a7%88%ec%9d%b4%ea%b7%b8%eb%a0%88%ec%9d%b4%ec%85%98%ec%9d%84-%ec%9c%84%ed%95%9c-depe","status":"publish","type":"post","link":"https:\/\/atmokpo.com\/w\/42921\/","title":{"rendered":"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774"},"content":{"rendered":"<p>WPF(Windows Presentation Foundation)\ub294 C#\uc73c\ub85c \ub370\uc2a4\ud06c\ud0d1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\uae30 \uc704\ud55c \uac15\ub825\ud55c \ud504\ub808\uc784\uc6cc\ud06c\uc785\ub2c8\ub2e4. \uc774 \uae00\uc5d0\uc11c\ub294 MVVM(Model-View-ViewModel) \ub514\uc790\uc778 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec WPF \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud560 \ub54c \ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529\uc758 \uace0\uae09 \ud65c\uc6a9 \ubc0f \ub9c8\uc774\uadf8\ub808\uc774\uc158 \uc2dc DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774\uc810\uc5d0 \ub300\ud574 \uae4a\uc774 \uc788\ub294 \uc124\uba85\uc744 \uc81c\uacf5\ud558\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<h2>1. MVVM \ub514\uc790\uc778 \ud328\ud134 \uac1c\uc694<\/h2>\n<p>MVVM\uc740 M(Model), V(View), VM(ViewModel) \uc138 \uac00\uc9c0 \uad6c\uc131 \uc694\uc18c\ub85c \ub098\ub269\ub2c8\ub2e4. \uc774 \ud328\ud134\uc740 UI \uc694\uc18c\uc640 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc744 \ubd84\ub9ac\ud568\uc73c\ub85c\uc368 \ucf54\ub4dc\uc758 \uc720\uc9c0 \ubcf4\uc218\uc131\uc744 \ub192\uc774\uace0, \ud14c\uc2a4\ud2b8 \uac00\ub2a5\uc131\uc744 \uc99d\uac00\uc2dc\ud0b5\ub2c8\ub2e4. View\ub294 \uc0ac\uc6a9\uc790 \uc778\ud130\ud398\uc774\uc2a4 \uc694\uc18c\ub85c \uad6c\uc131\ub418\uc5b4 \uc788\uc73c\uba70, ViewModel\uc740 View\uc640 Model \uac04\uc758 \ub370\uc774\ud130 \ubc14\uc778\ub529\uc744 \ucc98\ub9ac\ud558\ub294 \uc5ed\ud560\uc744 \uc218\ud589\ud569\ub2c8\ub2e4. Model\uc740 \ub370\uc774\ud130\uc640 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc744 \ud3ec\ud568\ud569\ub2c8\ub2e4.<\/p>\n<h2>2. \ucee4\ub9e8\ub4dc(Command)\uc640 \ubc14\uc778\ub529\uc758 \uace0\uae09 \ud65c\uc6a9<\/h2>\n<p>WPF\uc5d0\uc11c \ucee4\ub9e8\ub4dc\ub294 \uc0ac\uc6a9\uc790 \uc0c1\ud638\uc791\uc6a9\uc5d0 \ub300\ud55c \ub17c\ub9ac\ub97c \ucea1\uc290\ud654\ud569\ub2c8\ub2e4. \ucee4\ub9e8\ub4dc\ub97c \uc0ac\uc6a9\ud558\uba74 UI \uc694\uc18c\uc758 \ub3d9\uc791\uc744 ViewModel\uacfc \uc27d\uac8c \uc5f0\uacb0\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<h3>2.1 RelayCommand \ud074\ub798\uc2a4<\/h3>\n<p>RelayCommand\ub294 ICommand \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \ud074\ub798\uc2a4\uc785\ub2c8\ub2e4. \uc774 \ud074\ub798\uc2a4\ub294 \ud6e8\uc52c \ub354 \uc9c1\uad00\uc801\uc778 \ucee4\ub9e8\ub4dc\ub97c \uad6c\ud604\ud560 \uc218 \uc788\ub3c4\ub85d \ub3c4\uc640\uc90d\ub2c8\ub2e4. \ub2e4\uc74c\uc740 RelayCommand\uc758 \uae30\ubcf8 \uad6c\uc870\uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"csharp\">public class RelayCommand : ICommand\n{\n    private readonly Action&lt;object&gt; _execute;\n    private readonly Predicate&lt;object&gt; _canExecute;\n\n    public RelayCommand(Action&lt;object&gt; execute, Predicate&lt;object&gt; canExecute = null)\n    {\n        _execute = execute ?? throw new ArgumentNullException(nameof(execute));\n        _canExecute = canExecute;\n    }\n\n    public bool CanExecute(object parameter) =&gt; _canExecute == null || _canExecute(parameter);\n\n    public void Execute(object parameter) =&gt; _execute(parameter);\n\n    public event EventHandler CanExecuteChanged\n    {\n        add { CommandManager.RequerySuggested += value; }\n        remove { CommandManager.RequerySuggested -= value; }\n    }\n}<\/code><\/pre>\n<h3>2.2 ViewModel\uc5d0\uc11c RelayCommand \uc0ac\uc6a9\ud558\uae30<\/h3>\n<p>RelayCommand\ub97c ViewModel\uc5d0\uc11c \uc0ac\uc6a9\ud558\uc5ec UI\uc640 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc744 \ud6a8\uc728\uc801\uc73c\ub85c \uc5f0\uacb0\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc544\ub798\ub294 ViewModel\uc5d0\uc11c RelayCommand\ub97c \uc124\uc815\ud558\ub294 \uc608\uc81c\uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"csharp\">public class MainViewModel : INotifyPropertyChanged\n{\n    public ICommand SaveCommand { get; }\n\n    public MainViewModel()\n    {\n        SaveCommand = new RelayCommand(OnSave, CanSave);\n    }\n\n    private void OnSave(object parameter)\n    {\n        \/\/ \uc800\uc7a5 \ub85c\uc9c1 \uad6c\ud604\n    }\n\n    private bool CanSave(object parameter)\n    {\n        \/\/ \uc800\uc7a5 \uac00\ub2a5 \uc5ec\ubd80 \uacb0\uc815\n        return true; \/\/ \uc870\uac74\uc5d0 \ub530\ub77c \ubc18\ud658\n    }\n\n    \/\/ INotifyPropertyChanged \uad6c\ud604\n    public event PropertyChangedEventHandler PropertyChanged;\n    protected virtual void OnPropertyChanged(string propertyName) =&gt;\n        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));\n}<\/code><\/pre>\n<h3>2.3 XAML\uc5d0\uc11c \ucee4\ub9e8\ub4dc \ubc14\uc778\ub529<\/h3>\n<p>XAML\uc5d0\uc11c ViewModel\uc758 \ucee4\ub9e8\ub4dc\ub97c UI \uc694\uc18c\uc5d0 \ubc14\uc778\ub529\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc544\ub798\ub294 \ubc84\ud2bc\uc758 Click \uc774\ubca4\ud2b8\uc5d0 \ucee4\ub9e8\ub4dc\ub97c \ubc14\uc778\ub529\ud558\ub294 \ubc29\ubc95\uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"xml\">&lt;Button Content=\"Save\" Command=\"{Binding SaveCommand}\" \/&gt;<\/code><\/pre>\n<h2>3. DependencyProperty\uc640 INotifyPropertyChanged<\/h2>\n<p>WPF\uc5d0\uc11c\ub294 \ub370\uc774\ud130 \ubc14\uc778\ub529\uc744 \uc704\ud574 DependencyProperty\uc640 INotifyPropertyChanged\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ub450 \uae30\uc220\uc740 \uc11c\ub85c \ub2e4\ub978 \uc0c1\ud669\uc5d0\uc11c \uc720\uc6a9\ud558\uac8c \uc4f0\uc774\uba70, \uac01\uac01\uc758 \uc4f0\uc784\uc0c8\uc640 \uc7a5\ub2e8\uc810\uc774 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<h3>3.1 DependencyProperty<\/h3>\n<p>DependencyProperty\ub294 WPF\uc5d0\uc11c UI \uc694\uc18c\uc758 \ud2b9\uc131(property)\uc744 \uc815\uc758\ud558\ub294 \ub370 \uc0ac\uc6a9\ub429\ub2c8\ub2e4. DependencyProperty\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \ud2b9\uc9d5\uc744 \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4:<\/p>\n<ul>\n<li>\uc131\ub2a5 \ud5a5\uc0c1: WPF\ub294 DependencyProperty\ub97c \uc0ac\uc6a9\ud558\uc5ec \ubcc0\uacbd\ub41c \ud504\ub85c\ud37c\ud2f0\uc5d0 \ub300\ud55c \uc790\ub3d9 \uc5c5\ub370\uc774\ud2b8\ub97c \uc81c\uacf5\ud569\ub2c8\ub2e4.<\/li>\n<li>\ubaa8\ub4e0 \ube48 \uac1d\uccb4(Binding Target)\uc640\uc758 \ud638\ud658\uc131: \uc774\ub294 \ub2e4\uc591\ud55c \uc0ac\uc6a9\uc790 \uc815\uc758 \uc18d\uc131 \ubc0f \ub370\uc774\ud130 \ud15c\ud50c\ub9bf\uc744 \uc9c0\uc6d0\ud569\ub2c8\ub2e4.<\/li>\n<li>\uc2a4\ud0c0\uc77c\uacfc \uc560\ub2c8\uba54\uc774\uc158 \uc9c0\uc6d0: DependencyProperty\ub294 \uc2a4\ud0c0\uc77c \ubc0f \uc560\ub2c8\uba54\uc774\uc158\uc744 \uc27d\uac8c \uc801\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ub3c4\uc640\uc90d\ub2c8\ub2e4.<\/li>\n<\/ul>\n<p>DependencyProperty\ub97c \uc815\uc758\ud558\ub294 \ubc29\ubc95\uc740 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4:<\/p>\n<pre><code class=\"csharp\">public static readonly DependencyProperty MyPropertyProperty =\n    DependencyProperty.Register(\"MyProperty\", typeof(string), typeof(MyControl), new PropertyMetadata(string.Empty));\n\npublic string MyProperty\n{\n    get { return (string)GetValue(MyPropertyProperty); }\n    set { SetValue(MyPropertyProperty, value); }\n}<\/code><\/pre>\n<h3>3.2 INotifyPropertyChanged<\/h3>\n<p>INotifyPropertyChanged\ub294 \ub370\uc774\ud130 \ubc14\uc778\ub529\uc744 \uc704\ud55c \ud504\ub85c\ud37c\ud2f0\uc758 \ubcc0\uacbd \uc54c\ub9bc\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4. \uc774\ub294 \uc8fc\ub85c ViewModel\uc5d0\uc11c \ub370\uc774\ud130 \ubc14\uc778\ub529\uc744 \uad6c\ud604\ud560 \ub54c \uc0ac\uc6a9\ub429\ub2c8\ub2e4.<\/p>\n<p>INotifyPropertyChanged\ub97c \uc0ac\uc6a9\ud558\ub294 \uae30\ubcf8 \uad6c\ud604\uc740 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4:<\/p>\n<pre><code class=\"csharp\">public class MyViewModel : INotifyPropertyChanged\n{\n    private string _myProperty;\n    public string MyProperty\n    {\n        get { return _myProperty; }\n        set\n        {\n            if (_myProperty != value)\n            {\n                _myProperty = value;\n                OnPropertyChanged(nameof(MyProperty));\n            }\n        }\n    }\n\n    public event PropertyChangedEventHandler PropertyChanged;\n\n    protected virtual void OnPropertyChanged(string propertyName) =&gt;\n        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));\n}<\/code><\/pre>\n<h2>4. \ub9c8\uc774\uadf8\ub808\uc774\uc158 \uc2dc\uc758 \uace0\ub824 \uc0ac\ud56d<\/h2>\n<p>\ub9c8\uc774\uadf8\ub808\uc774\uc158 \uc2dc WPF \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \uc0ac\uc6a9\uc744 \uace0\ub824\ud574\uc57c \ud569\ub2c8\ub2e4. \ub450 \uae30\uc220\uc758 \uc120\ud0dd\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \uc694\uc18c\uc5d0 \uc758\ud574 \ub2ec\ub77c\uc9c8 \uc218 \uc788\uc2b5\ub2c8\ub2e4:<\/p>\n<ul>\n<li><strong>UI \uc694\uc18c\uc640\uc758 \uad00\uacc4:<\/strong> UI \uc694\uc18c\uc640 \ubc00\uc811\ud558\uac8c \uad00\ub828\ub41c \ud504\ub85c\ud37c\ud2f0\ub294 DependencyProperty\ub85c \uc815\uc758\ud558\ub294 \uac83\uc774 \uc88b\uc2b5\ub2c8\ub2e4.<\/li>\n<li><strong>\ub85c\uc9c1 \ud30c\ud2b8:<\/strong> \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc774\ub098 \ubcf5\uc7a1\ud55c \ub370\uc774\ud130 \uc0c1\ud0dc\ub97c \uad00\ub9ac\ud558\ub294 ViewModel\uc5d0\uc11c\ub294 INotifyPropertyChanged\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \ubc14\ub78c\uc9c1\ud569\ub2c8\ub2e4.<\/li>\n<\/ul>\n<h3>4.1 \ub9c8\uc774\uadf8\ub808\uc774\uc158 \uc608\uc2dc<\/h3>\n<p>\uc608\ub97c \ub4e4\uc5b4 \uc774\uc804 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \ub9e4\uac1c \ubcc0\uc218\ub97c DependencyProperty\ub85c \uc804\ud658\ud558\ub824\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uacfc\uc815\uc744 \uac70\uccd0\uc57c \ud569\ub2c8\ub2e4:<\/p>\n<pre><code class=\"csharp\">public class MyNewControl : Control\n{\n    public static readonly DependencyProperty MyDependencyProperty =\n        DependencyProperty.Register(\"MyDependency\", typeof(string), typeof(MyNewControl), new PropertyMetadata(string.Empty));\n\n    public string MyDependency\n    {\n        get { return (string)GetValue(MyDependencyProperty); }\n        set { SetValue(MyDependencyProperty, value); }\n    }\n}<\/code><\/pre>\n<p>\uc774\uc640 \uac19\uc740 \uacfc\uc815\uc744 \ud1b5\ud574 UI \uc694\uc18c\uc640\uc758 \uc0c1\ud638\uc791\uc6a9 \ube48\ub3c4\ub97c \uc904\uc774\uace0, \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc720\uc9c0 \ubcf4\uc218\ub97c \ub354\uc6b1 \uc6a9\uc774\ud558\uac8c \ub9cc\ub4e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<h2>5. \uacb0\ub860<\/h2>\n<p>\uc774\ubc88 \uae00\uc5d0\uc11c\ub294 WPF\uc5d0\uc11c MVVM \ud328\ud134\uc744 \ud65c\uc6a9\ud55c \ucee4\ub9e8\ub4dc \uc0ac\uc6a9 \ubc0f DependencyProperty\uc640 INotifyPropertyChanged \uac04\uc758 \ucc28\uc774\ub97c \ub2e4\ub918\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \uc6d0\ub9ac\ub97c \uc774\ud574\ud558\uace0 \ud65c\uc6a9\ud55c\ub2e4\uba74, \ub354\uc6b1 \ud6a8\uc728\uc801\uc774\uace0 \uc720\uc9c0 \ubcf4\uc218\ud558\uae30 \uc26c\uc6b4 WPF \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud560 \uc218 \uc788\uc744 \uac83\uc785\ub2c8\ub2e4. \ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529\uc758 \uc774\ud574\ub294 MVC, MVVM \ud328\ud134\uc744 \ub118\uc5b4 \ub354 \ub113\uc740 \uc601\uc5ed\uc73c\ub85c\uc758 \ud655\uc7a5\uc744 \uac00\ub2a5\ud558\uac8c \ud560 \uac83\uc785\ub2c8\ub2e4.<\/p>\n<p>\ucd94\uac00\uc801\uc73c\ub85c DependencyProperty\uc640 INotifyPropertyChanged\ub97c \uc798 \ud65c\uc6a9\ud568\uc73c\ub85c\uc368 WPF\uc758 \ud2b9\uc131\uc744 \ucd5c\ub300\ud55c \ud65c\uc6a9\ud560 \uc218 \uc788\uc73c\uba70, \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uacfc UI \ucf54\ub4dc \ubd84\ub9ac\ub97c \ud1b5\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ud488\uc9c8\uc744 \ud5a5\uc0c1\uc2dc\ud0ac \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uc790\uc8fc \ubc1c\uc0dd\ud558\ub294 \uc9c8\ubb38\uc774\ub098 \ucd94\uac00\uc801\uc778 \ucf54\ub4dc\uac00 \ud544\uc694\ud558\uc2dc\ub2e4\uba74 \ub313\uae00\uc744 \ub0a8\uaca8\uc8fc\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4. \ud568\uaed8 \uace0\ubbfc\ud558\uace0 \ubc1c\uc804\ud560 \uc218 \uc788\ub294 \ucee4\ubba4\ub2c8\ud2f0\uac00 \ub418\uae38 \ubc14\ub78d\ub2c8\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>WPF(Windows Presentation Foundation)\ub294 C#\uc73c\ub85c \ub370\uc2a4\ud06c\ud0d1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\uae30 \uc704\ud55c \uac15\ub825\ud55c \ud504\ub808\uc784\uc6cc\ud06c\uc785\ub2c8\ub2e4. \uc774 \uae00\uc5d0\uc11c\ub294 MVVM(Model-View-ViewModel) \ub514\uc790\uc778 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec WPF \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud560 \ub54c \ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529\uc758 \uace0\uae09 \ud65c\uc6a9 \ubc0f \ub9c8\uc774\uadf8\ub808\uc774\uc158 \uc2dc DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774\uc810\uc5d0 \ub300\ud574 \uae4a\uc774 \uc788\ub294 \uc124\uba85\uc744 \uc81c\uacf5\ud558\uaca0\uc2b5\ub2c8\ub2e4. 1. MVVM \ub514\uc790\uc778 \ud328\ud134 \uac1c\uc694 MVVM\uc740 M(Model), V(View), VM(ViewModel) \uc138 \uac00\uc9c0 \uad6c\uc131 \uc694\uc18c\ub85c \ub098\ub269\ub2c8\ub2e4. \uc774 \ud328\ud134\uc740 UI \uc694\uc18c\uc640 \ube44\uc988\ub2c8\uc2a4 &hellip; <a href=\"https:\/\/atmokpo.com\/w\/42921\/\" class=\"more-link\">\ub354 \ubcf4\uae30<span class=\"screen-reader-text\"> &#8220;[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[39],"tags":[],"class_list":["post-42921","post","type-post","status-publish","format-standard","hentry","category-wpf-"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774 - \ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/atmokpo.com\/w\/42921\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774 - \ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8\" \/>\n<meta property=\"og:description\" content=\"WPF(Windows Presentation Foundation)\ub294 C#\uc73c\ub85c \ub370\uc2a4\ud06c\ud0d1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\uae30 \uc704\ud55c \uac15\ub825\ud55c \ud504\ub808\uc784\uc6cc\ud06c\uc785\ub2c8\ub2e4. \uc774 \uae00\uc5d0\uc11c\ub294 MVVM(Model-View-ViewModel) \ub514\uc790\uc778 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec WPF \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud560 \ub54c \ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529\uc758 \uace0\uae09 \ud65c\uc6a9 \ubc0f \ub9c8\uc774\uadf8\ub808\uc774\uc158 \uc2dc DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774\uc810\uc5d0 \ub300\ud574 \uae4a\uc774 \uc788\ub294 \uc124\uba85\uc744 \uc81c\uacf5\ud558\uaca0\uc2b5\ub2c8\ub2e4. 1. MVVM \ub514\uc790\uc778 \ud328\ud134 \uac1c\uc694 MVVM\uc740 M(Model), V(View), VM(ViewModel) \uc138 \uac00\uc9c0 \uad6c\uc131 \uc694\uc18c\ub85c \ub098\ub269\ub2c8\ub2e4. \uc774 \ud328\ud134\uc740 UI \uc694\uc18c\uc640 \ube44\uc988\ub2c8\uc2a4 &hellip; \ub354 \ubcf4\uae30 &quot;[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774&quot;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/atmokpo.com\/w\/42921\/\" \/>\n<meta property=\"og:site_name\" content=\"\ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8\" \/>\n<meta property=\"article:published_time\" content=\"2024-11-13T22:28:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-11-26T06:34:27+00:00\" \/>\n<meta name=\"author\" content=\"root\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@bebubo4\" \/>\n<meta name=\"twitter:site\" content=\"@bebubo4\" \/>\n<meta name=\"twitter:label1\" content=\"\uae00\uc4f4\uc774\" \/>\n\t<meta name=\"twitter:data1\" content=\"root\" \/>\n\t<meta name=\"twitter:label2\" content=\"\uc608\uc0c1 \ub418\ub294 \ud310\ub3c5 \uc2dc\uac04\" \/>\n\t<meta name=\"twitter:data2\" content=\"2\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/atmokpo.com\/w\/42921\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/atmokpo.com\/w\/42921\/\"},\"author\":{\"name\":\"root\",\"@id\":\"https:\/\/atmokpo.com\/w\/#\/schema\/person\/91b6b3b138fbba0efb4ae64b1abd81d7\"},\"headline\":\"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774\",\"datePublished\":\"2024-11-13T22:28:14+00:00\",\"dateModified\":\"2024-11-26T06:34:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/atmokpo.com\/w\/42921\/\"},\"wordCount\":89,\"publisher\":{\"@id\":\"https:\/\/atmokpo.com\/w\/#organization\"},\"articleSection\":[\"WPF \uac1c\ubc1c\"],\"inLanguage\":\"ko-KR\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/atmokpo.com\/w\/42921\/\",\"url\":\"https:\/\/atmokpo.com\/w\/42921\/\",\"name\":\"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774 - \ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8\",\"isPartOf\":{\"@id\":\"https:\/\/atmokpo.com\/w\/#website\"},\"datePublished\":\"2024-11-13T22:28:14+00:00\",\"dateModified\":\"2024-11-26T06:34:27+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/atmokpo.com\/w\/42921\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/atmokpo.com\/w\/42921\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/atmokpo.com\/w\/42921\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\ud648\",\"item\":\"https:\/\/atmokpo.com\/w\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/atmokpo.com\/w\/#website\",\"url\":\"https:\/\/atmokpo.com\/w\/\",\"name\":\"\ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/atmokpo.com\/w\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/atmokpo.com\/w\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/atmokpo.com\/w\/#organization\",\"name\":\"\ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8\",\"url\":\"https:\/\/atmokpo.com\/w\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/atmokpo.com\/w\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/atmokpo.com\/w\/wp-content\/uploads\/2024\/11\/logo.png\",\"contentUrl\":\"https:\/\/atmokpo.com\/w\/wp-content\/uploads\/2024\/11\/logo.png\",\"width\":400,\"height\":400,\"caption\":\"\ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8\"},\"image\":{\"@id\":\"https:\/\/atmokpo.com\/w\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/bebubo4\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/atmokpo.com\/w\/#\/schema\/person\/91b6b3b138fbba0efb4ae64b1abd81d7\",\"name\":\"root\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/atmokpo.com\/w\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/708197b41fc6435a7ce22d951b25d4a47e9e904270cb1f04682d4f025066f80c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/708197b41fc6435a7ce22d951b25d4a47e9e904270cb1f04682d4f025066f80c?s=96&d=mm&r=g\",\"caption\":\"root\"},\"sameAs\":[\"http:\/\/atmokpo.com\/w\"],\"url\":\"https:\/\/atmokpo.com\/w\/author\/root\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774 - \ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/atmokpo.com\/w\/42921\/","og_locale":"ko_KR","og_type":"article","og_title":"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774 - \ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8","og_description":"WPF(Windows Presentation Foundation)\ub294 C#\uc73c\ub85c \ub370\uc2a4\ud06c\ud0d1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\uae30 \uc704\ud55c \uac15\ub825\ud55c \ud504\ub808\uc784\uc6cc\ud06c\uc785\ub2c8\ub2e4. \uc774 \uae00\uc5d0\uc11c\ub294 MVVM(Model-View-ViewModel) \ub514\uc790\uc778 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec WPF \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud560 \ub54c \ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529\uc758 \uace0\uae09 \ud65c\uc6a9 \ubc0f \ub9c8\uc774\uadf8\ub808\uc774\uc158 \uc2dc DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774\uc810\uc5d0 \ub300\ud574 \uae4a\uc774 \uc788\ub294 \uc124\uba85\uc744 \uc81c\uacf5\ud558\uaca0\uc2b5\ub2c8\ub2e4. 1. MVVM \ub514\uc790\uc778 \ud328\ud134 \uac1c\uc694 MVVM\uc740 M(Model), V(View), VM(ViewModel) \uc138 \uac00\uc9c0 \uad6c\uc131 \uc694\uc18c\ub85c \ub098\ub269\ub2c8\ub2e4. \uc774 \ud328\ud134\uc740 UI \uc694\uc18c\uc640 \ube44\uc988\ub2c8\uc2a4 &hellip; \ub354 \ubcf4\uae30 \"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774\"","og_url":"https:\/\/atmokpo.com\/w\/42921\/","og_site_name":"\ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8","article_published_time":"2024-11-13T22:28:14+00:00","article_modified_time":"2024-11-26T06:34:27+00:00","author":"root","twitter_card":"summary_large_image","twitter_creator":"@bebubo4","twitter_site":"@bebubo4","twitter_misc":{"\uae00\uc4f4\uc774":"root","\uc608\uc0c1 \ub418\ub294 \ud310\ub3c5 \uc2dc\uac04":"2\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/atmokpo.com\/w\/42921\/#article","isPartOf":{"@id":"https:\/\/atmokpo.com\/w\/42921\/"},"author":{"name":"root","@id":"https:\/\/atmokpo.com\/w\/#\/schema\/person\/91b6b3b138fbba0efb4ae64b1abd81d7"},"headline":"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774","datePublished":"2024-11-13T22:28:14+00:00","dateModified":"2024-11-26T06:34:27+00:00","mainEntityOfPage":{"@id":"https:\/\/atmokpo.com\/w\/42921\/"},"wordCount":89,"publisher":{"@id":"https:\/\/atmokpo.com\/w\/#organization"},"articleSection":["WPF \uac1c\ubc1c"],"inLanguage":"ko-KR"},{"@type":"WebPage","@id":"https:\/\/atmokpo.com\/w\/42921\/","url":"https:\/\/atmokpo.com\/w\/42921\/","name":"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774 - \ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8","isPartOf":{"@id":"https:\/\/atmokpo.com\/w\/#website"},"datePublished":"2024-11-13T22:28:14+00:00","dateModified":"2024-11-26T06:34:27+00:00","breadcrumb":{"@id":"https:\/\/atmokpo.com\/w\/42921\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/atmokpo.com\/w\/42921\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/atmokpo.com\/w\/42921\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\ud648","item":"https:\/\/atmokpo.com\/w\/en\/"},{"@type":"ListItem","position":2,"name":"[MVVM] 2.\ucee4\ub9e8\ub4dc\uc640 \ubc14\uc778\ub529 \uace0\uae09 \ud65c\uc6a9, \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc704\ud55c DependencyProperty\uc640 INotifyPropertyChanged\uc758 \ud65c\uc6a9 \ucc28\uc774"}]},{"@type":"WebSite","@id":"https:\/\/atmokpo.com\/w\/#website","url":"https:\/\/atmokpo.com\/w\/","name":"\ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8","description":"","publisher":{"@id":"https:\/\/atmokpo.com\/w\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/atmokpo.com\/w\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ko-KR"},{"@type":"Organization","@id":"https:\/\/atmokpo.com\/w\/#organization","name":"\ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8","url":"https:\/\/atmokpo.com\/w\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/atmokpo.com\/w\/#\/schema\/logo\/image\/","url":"https:\/\/atmokpo.com\/w\/wp-content\/uploads\/2024\/11\/logo.png","contentUrl":"https:\/\/atmokpo.com\/w\/wp-content\/uploads\/2024\/11\/logo.png","width":400,"height":400,"caption":"\ub77c\uc774\ube0c\uc2a4\ub9c8\ud2b8"},"image":{"@id":"https:\/\/atmokpo.com\/w\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/bebubo4"]},{"@type":"Person","@id":"https:\/\/atmokpo.com\/w\/#\/schema\/person\/91b6b3b138fbba0efb4ae64b1abd81d7","name":"root","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/atmokpo.com\/w\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/708197b41fc6435a7ce22d951b25d4a47e9e904270cb1f04682d4f025066f80c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/708197b41fc6435a7ce22d951b25d4a47e9e904270cb1f04682d4f025066f80c?s=96&d=mm&r=g","caption":"root"},"sameAs":["http:\/\/atmokpo.com\/w"],"url":"https:\/\/atmokpo.com\/w\/author\/root\/"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/posts\/42921","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/comments?post=42921"}],"version-history":[{"count":1,"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/posts\/42921\/revisions"}],"predecessor-version":[{"id":42922,"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/posts\/42921\/revisions\/42922"}],"wp:attachment":[{"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/media?parent=42921"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/categories?post=42921"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/atmokpo.com\/w\/wp-json\/wp\/v2\/tags?post=42921"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}