IT/C#

[C#] INotifyPropertyChanged Interface Example (feat. WinForm TextBox Binding)

Ella.J 2024. 5. 14. 14:35
728x90
반응형

 

INotifyPropertyChanged Interface Example

(System.ComponentModel)

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Windows.Forms;
 
namespace FormTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
 
            InitChannel();
        }
 
        Channel _ch;
        public void InitChannel()
        {
            string[] chState = { "IDLE""RUN""ERROR""DISCONNECTED" };
            cbChState.Items.AddRange(chState);
            cbChState.SelectedIndexChanged += chState_SelectedIndexChanged;
 
            _ch = new Channel(0, State.IDLE);
            // 속성 변경 이벤트 추가
            _ch.PropertyChanged += OnPropertyChanged;
            cbChState.SelectedIndex = (int)State.IDLE;
 
            // TextBox Binding 기능 추가
            var chBinding = new BindingSource();
            chBinding.DataSource = _ch;
            txtChVoltage.DataBindings.Add(new Binding("Text", chBinding, "Voltage"true, DataSourceUpdateMode.Never));
            txtChCurrent.DataBindings.Add(new Binding("Text", chBinding, "Current"true, DataSourceUpdateMode.Never));
        }
 
        private void chState_SelectedIndexChanged(object sender, EventArgs e)
        {
            // ComboBox 값이 변경될 때 마다 Channel State 변경
            _ch.State = (State)cbChState.SelectedIndex;
        }
    }
 
    public enum State
    {
        IDLE,
        RUN,
        ERROR,
        DISCONNECTED,
    }
 
    public class Channel : INotifyPropertyChanged
    {
        #region INotifiyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        // Notify Properties 속성이 변경되면 이벤트 발생
        // CallerMemberName 특성을 사용하는 경우 속성 이름을 문자열 인수로 전달할 필요 X
        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(thisnew PropertyChangedEventArgs(propertyName));
        }
        #endregion
 
        #region "Notify Properties"
        private State _state;
        private double _voltage;
        private double _current;
 
        public State State
        {
            get => _state;
            internal set
            {
                if (_state != value)
                {
                    _state = value;
                    NotifyPropertyChanged();
                }
            }
        }
 
        public double Voltage
        {
            get => _voltage;
            private set
            {
                if (_voltage != value)
                {
                    _voltage = value;
                    NotifyPropertyChanged();
                }
            }
        }
 
        public double Current
        {
            get => _current;
            private set
            {
                if (_current != value)
                {
                    _current = value;
                    NotifyPropertyChanged();
                }
            }
        }
        #endregion
 
        public int ChannelIndex;
        public Channel(int chIndex, State state)
        {
            ChannelIndex = chIndex;
            State = state;
            Start();
        }
 
        internal void Start()
        {
            // Channel Thread (ChannelLoop) 시작
            new Thread(ChannelLoop) { Name = $"CH{ChannelIndex}", IsBackground = true }.Start();
        }
 
        private void ChannelLoop()
        {
            bool chRun = true;
 
            while (chRun)
            {
                Wait(10);
 
                // Channel State 변경 시 Voltage, Current 속성 변경
                switch (State)
                {
                    case State.IDLE:
                        Voltage = 0.1;
                        Current = 0.1;
                        break;
                    case State.RUN:
                        Voltage = 1.3;
                        Current = 4.5;
                        break;
                    case State.ERROR:
                        Voltage = -1;
                        Current = -1;
                        break;
                    case State.DISCONNECTED:
                        Voltage = 0;
                        Current = 0;
                        chRun = false;
                        break;
                }
            }
        }
 
        public static void Wait(int milliseconds = 1)
        {
            int Timing = Environment.TickCount + milliseconds;
            while (Timing > Environment.TickCount)
            {
                Application.DoEvents();
                Thread.Sleep(1);
            }
        }
    }
}
 
cs

 

 

https://learn.microsoft.com/ko-kr/dotnet/api/system.componentmodel.inotifypropertychanged?view=net-8.0

 

INotifyPropertyChanged 인터페이스 (System.ComponentModel)

속성 값이 변경되었음을 클라이언트에 알립니다.

learn.microsoft.com

https://learn.microsoft.com/ko-kr/dotnet/api/system.componentmodel.inotifypropertychanged.propertychanged?view=net-8.0

 

INotifyPropertyChanged.PropertyChanged 이벤트 (System.ComponentModel)

속성 값이 변경될 때 발생합니다.

learn.microsoft.com

https://learn.microsoft.com/ko-kr/dotnet/api/system.windows.forms.control.databindings?view=windowsdesktop-8.0&WT.mc_id=DT-MVP-4038148

 

Control.DataBindings Property (System.Windows.Forms)

Gets the data bindings for the control.

learn.microsoft.com

 

 

TextBox Binding

WinForm의 경우, (System.Windows.Forms)

WPF의 경우,

MVVM 패턴을 사용하고 Xaml에 TwoWay-binding을 하기 위해 아래와 같이 쓴다.

<TextBox Name=" txtChVoltage" Width="100" Height="30"

Text="{Binding Voltage, UpdateSourceTrigger=PropertyChanged}"/>

 

728x90
반응형