IT/C#

[C#] Double Trackbar User Control 만들기

Ella.J 2023. 1. 12. 16:50
728x90
반응형

 

(화면 녹화 시 마우스 포인터 위치랑 다르게 녹화가 되었다... 어떻게 조정하는지 몰름,,, ㅠ)

 

User Control을 이용해서 Double Value 값을 가지는 Trackbar를 만들어봤습니다.

마우스가 이동할 때마다 새로 그리기 때문에 조금 버벅거림이 있고,, 부족한 부분이 많습니다...

필요하신 분들은 얼마든지 코드 참고하셔서 만들어 보시면 좋을 것 같습니다.

 

 

먼저, 프로젝트에서 UserControl을 생성해 줍니다.

저는 색상 범위를 넣고 필요한 값을 얻기 위해 ColorScalePicker.cs로 생성해 주었습니다.

 

디자이너에서는 단순하게 우측에 Panel 하나만 추가해 주었습니다.

우측 Panel에는 지정된 값을 적어주도록 했습니다.

 

그리고 전체 코드는 아래와 같습니다.

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
295
296
297
298
299
300
301
302
303
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 DoubleTrackbar
{
    public partial class ColorScalePicker : UserControl
    {
        public ColorScalePicker()
        {
            InitializeComponent();
            DrawControl();
            once = true;
 
            heatmapBmp = DrawHeatmapBmp();
            heatmapPnl.Size = new Size(16this.Height);
            this.Controls.Add(heatmapPnl);
            heatmapPnl.BackgroundImage = heatmapBmp;
            heatmapPnl.BackgroundImageLayout = ImageLayout.Stretch;
        }
 
        public event EventHandler MinValueChanged;
        public event EventHandler MaxValueChanged;
 
        int max = 255;
        int maxVal = 255;
        int min = 0;
        int minVal = 0;
        int interval = 10;
 
        int maxSlider = 1;
        int minSlider = 1;
        bool isMaxDown = false;
        bool isMinDown = false;
        bool once = false;
 
        public Bitmap heatmapBmp;
        public Panel heatmapPnl = new Panel();
 
        [Description("MaxScale"), Category()]
        public int MaxScale
        {
            get { return max; }
            set
            {
                max = value;
                if (!isMinDown || !isMaxDown)
                {
                    DrawScale();
                    DrawControl();
                }
            }
        }
 
        [Description("MinScale"), Category()]
        public int MinScale
        {
            get { return min; }
            set
            {
                min = value;
                if (!isMinDown || !isMaxDown)
                {
                    DrawScale();
                    DrawControl();
                }
            }
        }
 
        [Description("MaxValue"), Category()]
        public int MaxValue
        {
            get { return maxVal; }
            set
            {
                maxVal = value;
                if (!isMinDown || !isMaxDown)
                {
                    DrawScale();
                    DrawControl();
                }
            }
        }
 
        [Description("MinValue"), Category()]
        public int MinValue
        {
            get { return minVal; }
            set
            {
                minVal = value;
                if (!isMinDown || !isMaxDown)
                {
                    DrawScale();
                    DrawControl();
                }
            }
        }
 
        [Description("Interval"), Category()]
        public int Interval
        {
            get { return interval; }
            set
            {
                interval = value;
                if (!isMinDown || !isMaxDown)
                {
                    DrawScale();
                    DrawControl();
                }
            }
        }
 
        public void DrawControl()
        {
            try
            {
                if (!isMinDown || !isMaxDown) DrawControl(calHeightVal(minVal, min, max, this.Height), calHeightVal(maxVal, min, max, this.Height));
            }
            catch { }
        }
 
        private void DrawScale()
        {
            try
            {
                this.Refresh();
                double valTerm = (double)(maxVal - minVal) / interval;
                double scaleTerm = (double)(maxSlider - minSlider) / interval;
                using (var scale = this.panel2.CreateGraphics())
                {
                    for (int i = 0; i <= interval; i++)
                    {
                        if (i == 0)
                        {
                            scale.DrawString($"- {Math.Round(maxVal - (valTerm * i))}", Font, Brushes.Black, 0, (float)((this.Height - maxSlider) + (scaleTerm * i)));
                        }
                        else if (i == interval)
                        {
                            scale.DrawString($"- {Math.Round(maxVal - (valTerm * i))}", Font, Brushes.Black, 0, (float)((this.Height - maxSlider) + (scaleTerm * i) - 11));
                        }
                        else
                        {
                            scale.DrawString($"- {Math.Round(maxVal - (valTerm * i))}", Font, Brushes.Black, 0, (float)((this.Height - maxSlider) + (scaleTerm * i) - 5));
                        }
                    }
                }
                Application.DoEvents();
            }
            catch { }
        }
 
        private void DrawControl(int minPoint, int maxPoint)
        {
            try
            {
                this.Invalidate();
                this.Update();
                maxSlider = maxPoint;
                minSlider = minPoint;
                if (maxSlider > this.Height) maxSlider = this.Height;
                if (minSlider < 0) minSlider = 0;
 
                heatmapPnl.Location = new Point(0this.Height - maxSlider + 12);
                heatmapPnl.Height = maxSlider - minSlider - 20;
 
                using (var grp = this.CreateGraphics())
                {
                    grp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
 
                    //Max Scale - Max Value
                    grp.DrawLine(new Pen(Color.Black, 30), 000, (this.Height - maxPoint));
                    //Max Value - Min Value
                    //grp.DrawLine(new Pen(Color.Red, 7), 12, (this.Height - maxPoint + 10), 12, (this.Height - minPoint - 10));
                    //Min Value - Min Scale
                    grp.DrawLine(new Pen(Color.White, 30), 0, (this.Height - minPoint - 10), 0this.Height);
 
                    //Max Slider
                    grp.FillRectangle(new SolidBrush(Color.Orange), 0, (this.Height - maxPoint), 1510);
                    //Min Slider
                    grp.FillRectangle(new SolidBrush(Color.Orange), 0, (this.Height - minPoint - 10), 1510);
                }
 
                this.Update();
            }
            catch { }
        }
 
        private Bitmap DrawHeatmapBmp()
        {
            int step = 0;
            int offset = 0;
            int colorval = 255;
            Bitmap HeatmapImage = new Bitmap(1256);
            for (int i = 0; i < 256; i++)
            {
                if (colorval != 0)
                {
                    colorval = 255 - (4 * offset);
                    offset++;
                }
                if (colorval == -1)
                {
                    colorval = 0;
                }
 
                if (step == 0)
                    HeatmapImage.SetPixel(0, i, Color.FromArgb(255255, colorval));
                else if (step == 1)
                    HeatmapImage.SetPixel(0, i, Color.FromArgb(255, colorval, 0));
                else if (step == 2)
                    HeatmapImage.SetPixel(0, i, Color.FromArgb(colorval, 0255));
                else if (step == 3)
                    HeatmapImage.SetPixel(0, i, Color.FromArgb(00, colorval));
 
                if (colorval == 0)
                {
                    step++;
                    offset = 0;
                    colorval = 255;
                }
            }
            return HeatmapImage;
        }
 
        private void MoveProgress(int y, bool isMax)
        {
            try
            {
                if (y < 0) y = 0;
                if (y > this.Height) y = this.Height;
 
                if (isMax)
                {
                    MaxValue = calRealVal((this.Height - y), min, max, this.Height);
                    MaxValueChanged(MaxValue, new EventArgs());
                    Application.DoEvents();
                }
                else
                {
                    MinValue = calRealVal((this.Height - y), min, max, this.Height);
                    MinValueChanged(MinValue, new EventArgs());
                    Application.DoEvents();
                }
            }
            catch { }
        }
 
        private int calHeightVal(int val, int min, int max, int height)
        {
            return ((val - min) * height) / (max - min);
        }
 
        private int calRealVal(int x, int min, int max, int height)
        {
            return ((x * (max - min)) / (height)) + min;
        }
 
        private void DoubleTrackbar_MouseDown(object sender, MouseEventArgs e)
        {
            if (new Rectangle(5, (this.Height - maxSlider), 1515).Contains(e.Location)) isMaxDown = true;
            if (new Rectangle(5, (this.Height - minSlider - 10), 1515).Contains(e.Location)) isMinDown = true;
        }
 
        private void DoubleTrackbar_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMinDown) {
                minVal = calRealVal((this.Height - e.Y), min, max, this.Height);
                DrawScale(); 
                DrawControl(this.Height - e.Y, maxSlider); 
            }
            else if (isMaxDown) { 
                maxVal = calRealVal((this.Height - e.Y), min, max, this.Height);
                DrawScale(); 
                DrawControl(minSlider, this.Height - e.Y); 
            }
        }
 
        private void DoubleTrackbar_MouseUp(object sender, MouseEventArgs e)
        {
            if (isMaxDown) MoveProgress(e.Y, true);
            else if (isMinDown) MoveProgress(e.Y, false);
            isMaxDown = false;
            isMinDown = false;
            if (maxVal > MaxScale) maxVal = MaxScale;
            if (minVal < MinScale) minVal = MinScale;
            DrawScale();
            DrawControl();
        }
 
        private void DoubleTrackbar_Paint(object sender, PaintEventArgs e)
        {
            if (once) { once = false; DrawScale(); DrawControl(); }
        }
    }
}
cs

 

User Control에서 만들어준 Cetegory는 Main Form에서 User Control을 사용할 때

디자이너 속성창에서 혹은 코드 상에서 Get/Set 할 수 있습니다.

각각의 변수값은 다음과 같습니다.

 

 

혹시나 부족한 부분, 수정이 필요한 부분이 있거나

궁금하신 게 있으시면 언제든지 댓글 남겨주세요~ : )

 

728x90
반응형