티스토리 뷰

======================================================

안녕하세요 Doridori 입니다. 


이번 강의는 delegate 두번째 강의로 event에 대한 강의 입니다. 


실제로 delegate를 사용 할 때 가장 많아 사용 되는 이유이기도 하고 방법이기도 하니 꼭 잘 보셔서 챙겨 가셨으면 좋겠습니다. 

======================================================


Delegate 2 (delegate와 event)


Source UI) (거의 내용이 없어서 지난 강의 마지막 source부터 진행 하시면 됩니다)

Soruce 전체) Study_25_Delegate 2.zip

교재) 25강 Delegate 2 (delegate와 event).pdf








이번강의는 delegate와 event에 대한 강의 입니다. 


delegate의 경우 단독으로도 사용 할 수 있지만 가장 많이 사용되는 방법의 경우 event 와 함께 사용이 됩니다.

이번 강의를 준비 하면서 자료를 찾아 보는게 깊게 들어갈 수록 정리도 제대로 되있지 않는 부분이 많고 가장 중요한 핵심은 빠진 블로그나 강의들이 많아서, 처음에는 이것 저것 설명을 하려고 준비 하다가 너무 정신 없어 질 수 있어서 에메한 부분들은 빼버리고 초급 내용에 꼭 필요한,
- 왜 delegate와 event를 함께 써야하는지
- 어떤 상황에서 사용해야 하는지
에 대한 내용을 기준으로 강의를 진행 하였습니다. delegate 가 호출 되는 구조나 더 깊은 내용은 동작을 해보시고 더 찾아 보고 싶으실 때 검색 하셔서 보시면 머리가 아프실것 같습니다. (^^;; ㅎㅎㅎ)
제가 프로그램을 짤때 가장 신경 쓰는 부분이 event 시점인데 delegate 의 경우 자식 form의 event를 부모 form으로 보낼 방법을 찾다보니 자연스럽게 알아보게 되었습니다. (가장 쉽게 많이 사용되는 방법이라고 보시면 될것 같습니다.)

원래는 지난 강의에 함께 진행 하려고 했던 부분 입니다만 시간도 시간이고 event를 설명하기에 좋은 예제라고 생각되어 이번강의로 넘기게 된 부분입니다. 처음 계획은 picturebox를 이용해서 pizza가 만들어지는 과정을 이미지로 표현 하려고 하였는데 진행 내용을 확인하는데 조금더 알아보기 편해서 listbox에 내용을 추가해서 만들게 되었습니다. (강의 시간이 부족해서 ㅜㅠ;; 나중에 강의 완료 하고 아쉬우면 추가로 만들던지 해야 겠습니다. ^^;;)


강의)


이번강의는 다른 강의 때 보다 하고 싶은 애기가 많았는데 쓸데 없는 애기가 너무 많아지면 집중이 떨어질것 같아서 최대한 필요한 내용만 가지고 진행 했습니다. 


그래도 1시간 가까이 나왔네요;; 


원래는 중간에 끊고 두개의 강의로 만드는게 나을 것도 같았는데 멈출 타이밍을 못잡아서 그냥 쭉 진행 했습니다. m(__)m


중단점을 곳곳에 찍어놓고 꼭 따라가면서 source 가 어디로 진행 되는지 확인 해 보시면서 따라해 보시면 좋을것 같습니다.




Source)


기존 Main form에서는 Form 호출하는 부분과 order를 sub form으로 넘겨주는 부분에 대해서 추가 하여 전체 Source를 올렸습니다. 


지난강의와 달라진 점을 비교하면서 보셔도 좋을것 같습니다.


MainForm)


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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace _24_DelegatePizzaOrder
{
    public partial class Form1 : Form
    {
        public delegate int delFuncDow_Edge(int i);
        public delegate int delFuncTopping(string strOrder, int Ea);
        
        public delegate T delFunc<T>(T i);  // 함수 명 뒤에 <일반화 변수명 - 형식 매개 변수> 을 사용 할 경우 일반화 함수를 지정 할수 있음 (인자 값 Type에 신경 쓰지 않는 형태)
        public delegate A delTest<A>(A i);  // 문자 종류는 상관 없음 일반화 함수를 Delegate에도 적용할 수 있다는 점 (확장개념 일반화 delegate를 delegate의 특징이라고 보기는 어렵지 않을지)
 
        public delegate object delFuncO(object i); // var, object
        
        int _iTotalPrice = 0;
        
        public Form1()
        {
            InitializeComponent();
        }
 
        /// <summary>
        /// 주문하기 Button을 Click 했을 때 발생 하는 Event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOrder_Click(object sender, EventArgs e)
        {
            Dictionary<stringint> dPizzaOrder = new Dictionary<stringint>();  // Pizza 주문을 담을 그릇 (Key : 주문 종류, value : 개수)
 
            delFuncDow_Edge delDow = new delFuncDow_Edge(fDow);
            delFuncDow_Edge delEdge = new delFuncDow_Edge(fEdge);
 
            delFuncTopping delTopping = null;
 
 
            int iDowOrder = 0;
            int iEdgeOrder = 0;
 
            // 선택 도우 확인
            if (rdoDow1.Checked)
            {
                iDowOrder = 1;
                dPizzaOrder.Add("오리지널"1);
            }
            else if (rdoDow2.Checked)
            {
                iDowOrder = 2;
                dPizzaOrder.Add("씬"1);
            }
 
            //delDow(iDowOrder);
 
            // 선택 엣지 확인
            if (rdoEdge1.Checked)
            {
                iEdgeOrder = 1;
                dPizzaOrder.Add("리치골드"1);
            }
            else if (rdoEdge2.Checked)
            {
                iEdgeOrder = 2;
                dPizzaOrder.Add("치즈크러스터"1);
            }
 
            //delEdge(iEdgeOrder);
 
            fCallBackDelegate(iDowOrder, delDow);
            fCallBackDelegate(iEdgeOrder, delEdge);
 
 
            // 토핑 선택 확인
            if (cboxTopping1.Checked)
            {
                //delTopping = new delFuncTopping(fTopping1);
                delTopping += fTopping1;
                dPizzaOrder.Add("소세지", (int)numEa.Value);
            }
 
            if (cboxTopping2.Checked)
            {
                delTopping += fTopping2;
                dPizzaOrder.Add("감자", (int)numEa.Value);
            }
 
            if (cboxTopping3.Checked)
            {
                delTopping += fTopping3;
                dPizzaOrder.Add("치즈", (int)numEa.Value);
            }
 
            delTopping("토핑", (int)numEa.Value);
 
            flboxOrderRed("----------------------------------");
            flboxOrderRed(string.Format("전체 주문 가격은 {0}원 입니다.", _iTotalPrice));
 
 
            frmLoadling(dPizzaOrder);
        }
        
 
        #region Function
 
        /// <summary>
        /// O : 선택안함, 1 : 오리지널, 2 : 씬
        /// </summary>
        /// <param name="iOrder"></param>
        /// <returns></returns>
        private int fDow(int iOrder)
        {
            string strOrder = string.Empty;
            int iPrice = 0;
 
            if (iOrder == 1)
            {
                iPrice = 10000;
                strOrder = string.Format("도우는 오리지널을 선택 하셨습니다. ({0}원)", iPrice.ToString());
            }
            else if (iOrder == 2)
            {
                iPrice = 11000;
                strOrder = string.Format("도우는 씬을 선택 하셨습니다. ({0}원)", iPrice.ToString());
            }
            else
            {
                strOrder = "도우를 선택하지 않았습니다.";
            }
 
            flboxOrderRed(strOrder);
 
            return _iTotalPrice = _iTotalPrice + iPrice;
        }
 
        /// <summary>
        /// O : 선택안함, 1 : 리치골드, 2 : 치즈크러스터
        /// </summary>
        /// <param name="iOrder"></param>
        /// <returns></returns>
        private int fEdge(int iOrder)
        {
            string strOrder = string.Empty;
            int iPrice = 0;
 
            if (iOrder == 1)
            {
                iPrice = 1000;
                strOrder = string.Format("엣지는 리치골드를 선택 하셨습니다. ({0}원)", iPrice.ToString());
            }
            else if (iOrder == 2)
            {
                iPrice = 2000;
                strOrder = string.Format("엣지는 치즈크러스터를 선택 하셨습니다. ({0}원)", iPrice.ToString());
            }
            else
            {
                strOrder = "엣지는 선택하지 않았습니다.";
            }
 
            flboxOrderRed(strOrder);
 
            return _iTotalPrice = _iTotalPrice + iPrice;
        }
 
        public int fCallBackDelegate(int i, delFuncDow_Edge dFunction)
        {
            return dFunction(i);
        }
 
 
        private int fTopping1(string Order, int iEa)
        {
            string strOrder = string.Empty;
            int iPrice = iEa * 500;
 
            strOrder = string.Format("소세지 {0} {1} 개를 선택 하였습니다. : ({2}원 (1ea 500원)", Order, iEa, iPrice);
 
            flboxOrderRed(strOrder);
 
            return _iTotalPrice = _iTotalPrice + iPrice;
        }
 
        private int fTopping2(string Order, int iEa)
        {
            string strOrder = string.Empty;
            int iPrice = iEa * 200;
 
            strOrder = string.Format("감자 {0} {1} 개를 선택 하였습니다. : ({2}원 (1ea 200원)", Order, iEa, iPrice);
 
            flboxOrderRed(strOrder);
 
            return _iTotalPrice = _iTotalPrice + iPrice;
        }
 
        private int fTopping3(string Order, int iEa)
        {
            string strOrder = string.Empty;
            int iPrice = iEa * 300;
 
            strOrder = string.Format("치즈 {0} {1} 개를 선택 하였습니다. : ({2}원 (1ea 300원)", Order, iEa, iPrice);
 
            flboxOrderRed(strOrder);
 
            return _iTotalPrice = _iTotalPrice + iPrice;
        }
 
 
        private void flboxOrderRed(string strOrder)
        {
            lboxOrder.Items.Add(strOrder);
        }
 
        #endregion
 
        #region event 예제 
 
        frmPizza fPizza;
 
        /// <summary>
        /// 자식 form을 호출 하는 Logic (함수로 만들어 놓음)
        /// </summary>
        /// <param name="dPizzaOrder"></param>
        private void frmLoadling(Dictionary<stringint> dPizzaOrder)
        {
            if (fPizza != null)
            {
                fPizza.Dispose();
                fPizza = null;
            }
 
            fPizza = new frmPizza();
            fPizza.eventdelPizzaComplete += FPizza_eventdelPizzaComplete;
            fPizza.Show();
 
 
            fPizza.fPizzrCheck(dPizzaOrder);
 
 
            // Timer로 자식 Form의 진행 상황을 체크 하기 위한 Logic 1
 
            //_timer = new Timer();
            //_timer.Interval = 1000;
            //_timer.Tick += _timer_Tick;
            //_timer.Start();
 
        }
 
        // Timer로 자식 Form의 진행 상황을 체크 하기 위한 Logic 2
 
        //Timer _timer;
        //private void _timer_Tick(object sender, EventArgs e)
        //{
        //    if (fPizza.BOrderComplete)
        //    {
        //        flboxOrderRed("주문 완료 확인");
        //    }
        //}
 
 
        /// <summary>
        /// 자식 form에 대한 delegate event 함수 호출
        /// </summary>
        /// <param name="strResult"></param>
        /// <param name="iTime"></param>
        /// <returns></returns>
        private int FPizza_eventdelPizzaComplete(string strResult, int iTime)
        {
            flboxOrderRed("----------------------------------");
            flboxOrderRed(string.Format("{0} / 걸린 시간 : {1}", strResult, iTime));
 
            // 결과 값을 자식 form으로 return 해주기 위해 사용
            // 시간 계산을 해서 5분이 넘어 가면 -1
            if (iTime > 4000)
            {
                return -1;
            }
            else
            {
                return 0;
            }
        }
        #endregion
 
 
    }
}
 
cs



Sub Form) frmPizza


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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace _24_DelegatePizzaOrder
{
    public partial class frmPizza : Form
    {
        public delegate int delPizzaComplete(string strResult, int iTime);  // delegate 선언
        public event delPizzaComplete eventdelPizzaComplete;  // delegate event 선언
 
        private bool bOrderComplete = false;  // 제작이 완료 됬는지 확인 하는 Flag (부모 Form에서 timer로 체크할때 사용)
        // 캡슐화
        public bool BOrderComplete { get => bOrderComplete; set => bOrderComplete = value; }  
 
        public frmPizza()
        {
            InitializeComponent();
        }
 
        //public frmPizza(Dictionary<string, int> dPizzaOrder)
        //{
        //    InitializeComponent();
        //}
 
        private void btnClose_Click(object sender, EventArgs e)
        {
            Close();
        }
 
       
        /// <summary>
        /// pizza 주문 진행 상황을 표시 하기 위한 함수
        /// </summary>
        /// <param name="dPizzaOrder"></param>
        internal void fPizzrCheck(Dictionary<stringint> dPizzaOrder)
        {
            BOrderComplete = false;
 
            int iTotalTime = 0;
 
            foreach (KeyValuePair<string,int> oOrder in dPizzaOrder)
            {
                int iNowTime = 0;
                string strType = string.Empty;
                int iTime = 0;
                int iCount = oOrder.Value;
 
                switch (oOrder.Key)
                {
                    // 도우
                    case "오리지널":
                        iNowTime = 3000;
                        strType = "도우";
                        break;
                    case "씬":
                        iNowTime = 3500;
                        strType = "도우";
                        break;
 
                    // 엣지
                    case "리치골드":
                        iNowTime = 500;
                        strType = "엣지";
                        break;
                    case "치즈크러스터":
                        iNowTime = 400;
                        strType = "엣지";
                        break;
 
                    // 토핑
                    case "소세지":
                        iNowTime = 32;
                        strType = "토핑";
                        break;
                    case "감자":
                        iNowTime = 17;
                        strType = "토핑";
                        break;
                    case "치즈":
                        iNowTime = 48;
                        strType = "토핑";
                        break;
 
                    default:
                        break;
                }
 
                iTime = iNowTime * iCount;
 
                iTotalTime = iTotalTime + iTime;
 
                lboxMake.Items.Add(string.Format("{0}) {1} : {2}초 ({3}초, {4}개)", strType, oOrder.Key, iTime, iNowTime, iCount));
 
                Refresh();
                Thread.Sleep(1000);
            }
            
            int iRet = eventdelPizzaComplete("Pizza가 완성 되었습니다.", iTotalTime);
 
            BOrderComplete = true;
 
            lboxMake.Items.Add("-------------------");
 
            if (iRet == 0)
            {
                lboxMake.Items.Add("주문 완료 확인!!");
            }
            else
            {
                lboxMake.Items.Add("제작 시간 초과로 고객 반품!!!");
            }
        }
    }
}
 
cs



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함