以下为工作中遇到的,备注一下
先需要几个辅助类
1 #region GripBounds
2
3 using System.Drawing;
4 internal struct GripBounds
5 {
6 private const int GripSize = 6;
7 private const int CornerGripSize = GripSize << 1;
8
9 public GripBounds(Rectangle clientRectangle)
10 {
11 this.clientRectangle = clientRectangle;
12 }
13
14 private Rectangle clientRectangle;
15 public Rectangle ClientRectangle
16 {
17 get { return clientRectangle; }
18 //set { clientRectangle = value; }
19 }
20
21 public Rectangle Bottom
22 {
23 get
24 {
25 Rectangle rect = ClientRectangle;
26 rect.Y = rect.Bottom - GripSize + 1;
27 rect.Height = GripSize;
28 return rect;
29 }
30 }
31
32 public Rectangle BottomRight
33 {
34 get
35 {
36 Rectangle rect = ClientRectangle;
37 rect.Y = rect.Bottom - CornerGripSize + 1;
38 rect.Height = CornerGripSize;
39 rect.X = rect.Width - CornerGripSize + 1;
40 rect.Width = CornerGripSize;
41 return rect;
42 }
43 }
44
45 public Rectangle Top
46 {
47 get
48 {
49 Rectangle rect = ClientRectangle;
50 rect.Height = GripSize;
51 return rect;
52 }
53 }
54
55 public Rectangle TopRight
56 {
57 get
58 {
59 Rectangle rect = ClientRectangle;
60 rect.Height = CornerGripSize;
61 rect.X = rect.Width - CornerGripSize + 1;
62 rect.Width = CornerGripSize;
63 return rect;
64 }
65 }
66
67 public Rectangle Left
68 {
69 get
70 {
71 Rectangle rect = ClientRectangle;
72 rect.Width = GripSize;
73 return rect;
74 }
75 }
76
77 public Rectangle BottomLeft
78 {
79 get
80 {
81 Rectangle rect = ClientRectangle;
82 rect.Width = CornerGripSize;
83 rect.Y = rect.Height - CornerGripSize + 1;
84 rect.Height = CornerGripSize;
85 return rect;
86 }
87 }
88
89 public Rectangle Right
90 {
91 get
92 {
93 Rectangle rect = ClientRectangle;
94 rect.X = rect.Right - GripSize + 1;
95 rect.Width = GripSize;
96 return rect;
97 }
98 }
99
100 public Rectangle TopLeft
101 {
102 get
103 {
104 Rectangle rect = ClientRectangle;
105 rect.Width = CornerGripSize;
106 rect.Height = CornerGripSize;
107 return rect;
108 }
109 }
110 }
111
112 #endregion
1 #region UnsafeMethods
2
3 using System;
4 using System.Drawing;
5 using System.Runtime.InteropServices;
6 internal class UnsafeMethods
7 {
8 public static readonly IntPtr TRUE = new IntPtr(1);
9 public static readonly IntPtr FALSE = new IntPtr(0);
10
11 public const int WM_LBUTTONDOWN = 0x201;
12 public const int WM_RBUTTONDOWN = 0x204;
13 public const int WM_MBUTTONDOWN = 0x207;
14 public const int WM_NCLBUTTONDOWN = 0x0A1;
15 public const int WM_NCRBUTTONDOWN = 0x0A4;
16 public const int WM_NCMBUTTONDOWN = 0x0A7;
17 public const int WM_NCCALCSIZE = 0x0083;
18 public const int WM_NCHITTEST = 0x0084;
19 public const int WM_NCPAINT = 0x0085;
20 public const int WM_NCACTIVATE = 0x0086;
21 public const int WM_MOUSELEAVE = 0x02A3;
22 public const int WS_EX_NOACTIVATE = 0x08000000;
23 public const int HTTRANSPARENT = -1;
24 public const int HTLEFT = 10;
25 public const int HTRIGHT = 11;
26 public const int HTTOP = 12;
27 public const int HTTOPLEFT = 13;
28 public const int HTTOPRIGHT = 14;
29 public const int HTBOTTOM = 15;
30 public const int HTBOTTOMLEFT = 16;
31 public const int HTBOTTOMRIGHT = 17;
32 public const int WM_USER = 0x0400;
33 public const int WM_REFLECT = WM_USER + 0x1C00;
34 public const int WM_COMMAND = 0x0111;
35 public const int CBN_DROPDOWN = 7;
36 public const int WM_GETMINMAXINFO = 0x0024;
37
38 public enum TrackerEventFlags : uint
39 {
40 TME_HOVER = 0x00000001,
41 TME_LEAVE = 0x00000002,
42 TME_QUERY = 0x40000000,
43 TME_CANCEL = 0x80000000
44 }
45
46 [DllImport("user32.dll")]
47 public static extern IntPtr GetWindowDC(IntPtr hWnd);
48
49 [DllImport("user32.dll")]
50 public static extern int ReleaseDC(IntPtr hwnd, IntPtr hDC);
51
52 [DllImport("user32")]
53 public static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack);
54
55 [DllImport("user32.dll")]
56 public static extern bool SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
57
58 internal static int HIWORD(int n)
59 {
60 return (n >> 16) & 0xffff;
61 }
62
63 internal static int HIWORD(IntPtr n)
64 {
65 return HIWORD(unchecked((int)(long)n));
66 }
67
68 internal static int LOWORD(int n)
69 {
70 return n & 0xffff;
71 }
72
73 internal static int LOWORD(IntPtr n)
74 {
75 return LOWORD(unchecked((int)(long)n));
76 }
77
78 [StructLayout(LayoutKind.Sequential)]
79 internal struct TRACKMOUSEEVENT
80 {
81 public uint cbSize;
82 public uint dwFlags;
83 public IntPtr hwndTrack;
84 public uint dwHoverTime;
85 }
86
87 [StructLayout(LayoutKind.Sequential)]
88 internal struct MINMAXINFO
89 {
90 public Point reserved;
91 public Size maxSize;
92 public Point maxPosition;
93 public Size minTrackSize;
94 public Size maxTrackSize;
95 }
96
97 #region RECT structure
98
99 [StructLayout(LayoutKind.Sequential)]
100 internal struct RECT
101 {
102 public int left;
103 public int top;
104 public int right;
105 public int bottom;
106
107 public RECT(int left, int top, int right, int bottom)
108 {
109 this.left = left;
110 this.top = top;
111 this.right = right;
112 this.bottom = bottom;
113 }
114
115 public Rectangle Rect
116 {
117 get
118 {
119 return new Rectangle(
120 this.left,
121 this.top,
122 this.right - this.left,
123 this.bottom - this.top);
124 }
125 }
126
127 public static RECT FromXYWH(int x, int y, int width, int height)
128 {
129 return new RECT(x,
130 y,
131 x + width,
132 y + height);
133 }
134
135 public static RECT FromRectangle(Rectangle rect)
136 {
137 return new RECT(rect.Left,
138 rect.Top,
139 rect.Right,
140 rect.Bottom);
141 }
142 }
143
144 #endregion RECT structure
145
146 #region WINDOWPOS
147
148 [StructLayout(LayoutKind.Sequential)]
149 internal struct WINDOWPOS
150 {
151 internal IntPtr hwnd;
152 internal IntPtr hWndInsertAfter;
153 internal int x;
154 internal int y;
155 internal int cx;
156 internal int cy;
157 internal uint flags;
158 }
159 #endregion
160
161 #region NCCALCSIZE_PARAMS
162 //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowstructures/nccalcsize_params.asp
163 [StructLayout(LayoutKind.Sequential)]
164 public struct NCCALCSIZE_PARAMS
165 {
166 /// <summary>
167 /// Contains the new coordinates of a window that has been moved or resized, that is, it is the proposed new window coordinates.
168 /// </summary>
169 public RECT rectProposed;
170 /// <summary>
171 /// Contains the coordinates of the window before it was moved or resized.
172 /// </summary>
173 public RECT rectBeforeMove;
174 /// <summary>
175 /// Contains the coordinates of the window's client area before the window was moved or resized.
176 /// </summary>
177 public RECT rectClientBeforeMove;
178 /// <summary>
179 /// Pointer to a WINDOWPOS structure that contains the size and position values specified in the operation that moved or resized the window.
180 /// </summary>
181 public WINDOWPOS lpPos;
182 }
183
184 #endregion
185 }
186
187 #endregion
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Drawing.Drawing2D;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.Security.Permissions;
10 using System.Runtime.InteropServices;
11 using VS = System.Windows.Forms.VisualStyles;
12
13 /*
14 <li>Base class for custom tooltips.</li>
15 <li>Office-2007-like tooltip class.</li>
16 */
17 namespace ZhuoYueE.Bpc.Controls
18 {
19 /// <summary>
20 /// Represents a pop-up window.
21 /// </summary>
22 [ToolboxItem(false)]
23 public partial class PopupForm : ToolStripDropDown
24 {
25 #region " Fields & Properties "
26
27 private Control content;
28 /// <summary>
29 /// Gets the content of the pop-up.
30 /// </summary>
31 public Control Content
32 {
33 get { return content; }
34 }
35
36 private bool fade;
37 /// <summary>
38 /// Gets a value indicating whether the <see cref="PopupControl.Popup"/> uses the fade effect.
39 /// </summary>
40 /// <value><c>true</c> if pop-up uses the fade effect; otherwise, <c>false</c>.</value>
41 /// <remarks>To use the fade effect, the FocusOnOpen property also has to be set to <c>true</c>.</remarks>
42 public bool UseFadeEffect
43 {
44 get { return fade; }
45 set
46 {
47 if (fade == value) return;
48 fade = value;
49 }
50 }
51
52 private bool focusOnOpen = true;
53 /// <summary>
54 /// Gets or sets a value indicating whether the content should receive the focus after the pop-up has been opened.
55 /// </summary>
56 /// <value><c>true</c> if the content should be focused after the pop-up has been opened; otherwise, <c>false</c>.</value>
57 /// <remarks>If the FocusOnOpen property is set to <c>false</c>, then pop-up cannot use the fade effect.</remarks>
58 public bool FocusOnOpen
59 {
60 get { return focusOnOpen; }
61 set { focusOnOpen = value; }
62 }
63
64 private bool acceptAlt = true;
65 /// <summary>
66 /// Gets or sets a value indicating whether presing the alt key should close the pop-up.
67 /// </summary>
68 /// <value><c>true</c> if presing the alt key does not close the pop-up; otherwise, <c>false</c>.</value>
69 public bool AcceptAlt
70 {
71 get { return acceptAlt; }
72 set { acceptAlt = value; }
73 }
74
75 private PopupForm ownerPopup;
76 private PopupForm childPopup;
77
78 private bool _resizable;
79 private bool resizable;
80 /// <summary>
81 /// Gets or sets a value indicating whether the <see cref="PopupControl.Popup" /> is resizable.
82 /// </summary>
83 /// <value><c>true</c> if resizable; otherwise, <c>false</c>.</value>
84 public bool Resizable
85 {
86 get { return resizable && _resizable; }
87 set { resizable = value; }
88 }
89
90 private ToolStripControlHost host;
91
92 private Size minSize;
93 /// <summary>
94 /// Gets or sets a minimum size of the pop-up.
95 /// </summary>
96 /// <returns>An ordered pair of type <see cref="T:System.Drawing.Size" /> representing the width and height of a rectangle.</returns>
97 public new Size MinimumSize
98 {
99 get { return minSize; }
100 set { minSize = value; }
101 }
102
103 private Size maxSize;
104 /// <summary>
105 /// Gets or sets a maximum size of the pop-up.
106 /// </summary>
107 /// <returns>An ordered pair of type <see cref="T:System.Drawing.Size" /> representing the width and height of a rectangle.</returns>
108 public new Size MaximumSize
109 {
110 get { return maxSize; }
111 set { maxSize = value; }
112 }
113
114 private bool _isOpen;
115
116 public bool IsOpen
117 {
118 get { return _isOpen; }
119 }
120
121 /// <summary>
122 /// Gets parameters of a new window.
123 /// </summary>
124 /// <returns>An object of type <see cref="T:System.Windows.Forms.CreateParams" /> used when creating a new window.</returns>
125 protected override CreateParams CreateParams
126 {
127 [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
128 get
129 {
130 CreateParams cp = base.CreateParams;
131 cp.ExStyle |= UnsafeMethods.WS_EX_NOACTIVATE;
132 return cp;
133 }
134 }
135
136 #endregion
137
138 #region " Constructors "
139
140 /// <summary>
141 /// Initializes a new instance of the <see cref="PopupControl.Popup"/> class.
142 /// </summary>
143 /// <param name="content">The content of the pop-up.</param>
144 /// <remarks>
145 /// Pop-up will be disposed immediately after disposion of the content control.
146 /// </remarks>
147 /// <exception cref="T:System.ArgumentNullException"><paramref name="content" /> is <code>null</code>.</exception>
148 public PopupForm(Control content)
149 {
150 if (content == null)
151 {
152 throw new ArgumentNullException("content");
153 }
154 this.content = content;
155 this.fade = SystemInformation.IsMenuAnimationEnabled && SystemInformation.IsMenuFadeEnabled;
156 this._resizable = true;
157 AutoSize = false;
158 DoubleBuffered = true;
159 ResizeRedraw = true;
160 host = new ToolStripControlHost(content);
161 Padding = Margin = host.Padding = host.Margin = Padding.Empty;
162 MinimumSize = content.MinimumSize;
163 content.MinimumSize = content.Size;
164 MaximumSize = content.MaximumSize;
165 content.MaximumSize = content.Size;
166 Size = content.Size;
167 content.Location = Point.Empty;
168 Items.Add(host);
169 content.Disposed += delegate(object sender, EventArgs e)
170 {
171 content = null;
172 Dispose(true);
173 };
174 content.RegionChanged += delegate(object sender, EventArgs e)
175 {
176 UpdateRegion();
177 };
178 content.Paint += delegate(object sender, PaintEventArgs e)
179 {
180 PaintSizeGrip(e);
181 };
182 UpdateRegion();
183 }
184
185 #endregion
186
187 #region " Methods "
188
189 /// <summary>
190 /// Processes a dialog box key.
191 /// </summary>
192 /// <param name="keyData">One of the <see cref="T:System.Windows.Forms.Keys" /> values that represents the key to process.</param>
193 /// <returns>
194 /// true if the key was processed by the control; otherwise, false.
195 /// </returns>
196 protected override bool ProcessDialogKey(Keys keyData)
197 {
198 if (acceptAlt && ((keyData & Keys.Alt) == Keys.Alt))
199 {
200 if ((keyData & Keys.F4) != Keys.F4)
201 {
202 return false;
203 }
204 else
205 {
206 this.Close();
207 }
208 }
209 return base.ProcessDialogKey(keyData);
210 }
211
212 /// <summary>
213 /// Updates the pop-up region.
214 /// </summary>
215 protected void UpdateRegion()
216 {
217 if (this.Region != null)
218 {
219 this.Region.Dispose();
220 this.Region = null;
221 }
222 if (content.Region != null)
223 {
224 this.Region = content.Region.Clone();
225 }
226 }
227
228 /// <summary>
229 /// Shows the pop-up window below the specified control.
230 /// </summary>
231 /// <param name="control">The control below which the pop-up will be shown.</param>
232 /// <remarks>
233 /// When there is no space below the specified control, the pop-up control is shown above it.
234 /// </remarks>
235 /// <exception cref="T:System.ArgumentNullException"><paramref name="control"/> is <code>null</code>.</exception>
236 public void Show(Control control)
237 {
238 Show(control, control.ClientRectangle);
239 }
240
241 public void Show(Control control, bool center)
242 {
243 Show(control, control.ClientRectangle, center);
244 }
245
246 /// <summary>
247 /// Shows the pop-up window below the specified area of the specified control.
248 /// </summary>
249 /// <param name="control">The control used to compute screen location of specified area.</param>
250 /// <param name="area">The area of control below which the pop-up will be shown.</param>
251 /// <remarks>
252 /// When there is no space below specified area, the pop-up control is shown above it.
253 /// </remarks>
254 /// <exception cref="T:System.ArgumentNullException"><paramref name="control"/> is <code>null</code>.</exception>
255 public void Show(Control control, Rectangle area)
256 {
257 Show(control, area, false);
258 }
259
260 public void Show(Control control, Rectangle area, bool center)
261 {
262 if (control == null)
263 {
264 throw new ArgumentNullException("control");
265 }
266 SetOwnerItem(control);
267 resizableTop = resizableLeft = false;
268 Point location = control.PointToScreen(new Point(area.Left, area.Top + area.Height));
269 Rectangle screen = Screen.FromControl(control).WorkingArea;
270 if (center)
271 {
272 if (location.X + (area.Width + Size.Width) / 2 > screen.Right)
273 {
274 resizableLeft = true;
275 location.X = screen.Right - Size.Width;
276 }
277 else
278 {
279 resizableLeft = true;
280 location.X = location.X - (Size.Width - area.Width) / 2;
281 }
282 }
283 else
284 {
285 if (location.X + Size.Width > (screen.Left + screen.Width))
286 {
287 resizableLeft = true;
288 location.X = (screen.Left + screen.Width) - Size.Width;
289 }
290 }
291
292 if (location.Y + Size.Height > (screen.Top + screen.Height))
293 {
294 resizableTop = true;
295 location.Y -= Size.Height + area.Height;
296 }
297 location = control.PointToClient(location);
298 Show(control, location, ToolStripDropDownDirection.BelowRight);
299 }
300
301 private const int frames = 5;
302 private const int totalduration = 100;
303 private const int frameduration = totalduration / frames;
304 /// <summary>
305 /// Adjusts the size of the owner <see cref="T:System.Windows.Forms.ToolStrip" /> to accommodate the <see cref="T:System.Windows.Forms.ToolStripDropDown" /> if the owner <see cref="T:System.Windows.Forms.ToolStrip" /> is currently displayed, or clears and resets active <see cref="T:System.Windows.Forms.ToolStripDropDown" /> child controls of the <see cref="T:System.Windows.Forms.ToolStrip" /> if the <see cref="T:System.Windows.Forms.ToolStrip" /> is not currently displayed.
306 /// </summary>
307 /// <param name="visible">true if the owner <see cref="T:System.Windows.Forms.ToolStrip" /> is currently displayed; otherwise, false.</param>
308 protected override void SetVisibleCore(bool visible)
309 {
310 double opacity = Opacity;
311 if (visible && fade && focusOnOpen) Opacity = 0;
312 base.SetVisibleCore(visible);
313 if (!visible || !fade || !focusOnOpen) return;
314 for (int i = 1; i <= frames; i++)
315 {
316 if (i > 1)
317 {
318 System.Threading.Thread.Sleep(frameduration);
319 }
320 Opacity = opacity * (double)i / (double)frames;
321 }
322 Opacity = opacity;
323 }
324
325 private bool resizableTop;
326 private bool resizableLeft;
327
328 private void SetOwnerItem(Control control)
329 {
330 if (control == null)
331 {
332 return;
333 }
334 if (control is PopupForm)
335 {
336 PopupForm popupControl = control as PopupForm;
337 ownerPopup = popupControl;
338 ownerPopup.childPopup = this;
339 OwnerItem = popupControl.Items[0];
340 return;
341 }
342 if (control.Parent != null)
343 {
344 SetOwnerItem(control.Parent);
345 }
346 }
347
348 /// <summary>
349 /// Raises the <see cref="E:System.Windows.Forms.Control.SizeChanged" /> event.
350 /// </summary>
351 /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
352 protected override void OnSizeChanged(EventArgs e)
353 {
354 content.MinimumSize = Size;
355 content.MaximumSize = Size;
356 content.Size = Size;
357 content.Location = Point.Empty;
358 base.OnSizeChanged(e);
359 }
360
361 /// <summary>
362 /// Raises the <see cref="E:System.Windows.Forms.ToolStripDropDown.Opening" /> event.
363 /// </summary>
364 /// <param name="e">A <see cref="T:System.ComponentModel.CancelEventArgs" /> that contains the event data.</param>
365 protected override void OnOpening(CancelEventArgs e)
366 {
367 if (content.IsDisposed || content.Disposing)
368 {
369 e.Cancel = true;
370 return;
371 }
372 UpdateRegion();
373 base.OnOpening(e);
374 }
375
376 /// <summary>
377 /// Raises the <see cref="E:System.Windows.Forms.ToolStripDropDown.Opened" /> event.
378 /// </summary>
379 /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
380 protected override void OnOpened(EventArgs e)
381 {
382 if (ownerPopup != null)
383 {
384 ownerPopup._resizable = false;
385 }
386 if (focusOnOpen)
387 {
388 content.Focus();
389 }
390 _isOpen = true;
391 base.OnOpened(e);
392 }
393
394 /// <summary>
395 /// Raises the <see cref="E:System.Windows.Forms.ToolStripDropDown.Closed"/> event.
396 /// </summary>
397 /// <param name="e">A <see cref="T:System.Windows.Forms.ToolStripDropDownClosedEventArgs"/> that contains the event data.</param>
398 protected override void OnClosed(ToolStripDropDownClosedEventArgs e)
399 {
400 if (ownerPopup != null)
401 {
402 ownerPopup._resizable = true;
403 }
404 _isOpen = false;
405 base.OnClosed(e);
406 }
407
408 #endregion
409
410 #region " Resizing Support "
411
412 /// <summary>
413 /// Processes Windows messages.
414 /// </summary>
415 /// <param name="m">The Windows <see cref="T:System.Windows.Forms.Message" /> to process.</param>
416 [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
417 protected override void WndProc(ref Message m)
418 {
419 if (InternalProcessResizing(ref m, false))
420 {
421 return;
422 }
423 base.WndProc(ref m);
424 }
425
426 /// <summary>
427 /// Processes the resizing messages.
428 /// </summary>
429 /// <param name="m">The message.</param>
430 /// <returns>true, if the WndProc method from the base class shouldn't be invoked.</returns>
431 [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
432 public bool ProcessResizing(ref Message m)
433 {
434 return InternalProcessResizing(ref m, true);
435 }
436
437 [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
438 private bool InternalProcessResizing(ref Message m, bool contentControl)
439 {
440 if (m.Msg == UnsafeMethods.WM_NCACTIVATE && m.WParam != IntPtr.Zero && childPopup != null && childPopup.Visible)
441 {
442 childPopup.Hide();
443 }
444 if (!Resizable)
445 {
446 return false;
447 }
448 if (m.Msg == UnsafeMethods.WM_NCHITTEST)
449 {
450 return OnNcHitTest(ref m, contentControl);
451 }
452 else if (m.Msg == UnsafeMethods.WM_GETMINMAXINFO)
453 {
454 return OnGetMinMaxInfo(ref m);
455 }
456 return false;
457 }
458
459 [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
460 private bool OnGetMinMaxInfo(ref Message m)
461 {
462 UnsafeMethods.MINMAXINFO minmax = (UnsafeMethods.MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(UnsafeMethods.MINMAXINFO));
463 minmax.maxTrackSize = this.MaximumSize;
464 minmax.minTrackSize = this.MinimumSize;
465 Marshal.StructureToPtr(minmax, m.LParam, false);
466 return true;
467 }
468
469 private bool OnNcHitTest(ref Message m, bool contentControl)
470 {
471 int x = UnsafeMethods.LOWORD(m.LParam);
472 int y = UnsafeMethods.HIWORD(m.LParam);
473 Point clientLocation = PointToClient(new Point(x, y));
474
475 GripBounds gripBouns = new GripBounds(contentControl ? content.ClientRectangle : ClientRectangle);
476 IntPtr transparent = new IntPtr(UnsafeMethods.HTTRANSPARENT);
477
478 if (resizableTop)
479 {
480 if (resizableLeft && gripBouns.TopLeft.Contains(clientLocation))
481 {
482 m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTTOPLEFT;
483 return true;
484 }
485 if (!resizableLeft && gripBouns.TopRight.Contains(clientLocation))
486 {
487 m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTTOPRIGHT;
488 return true;
489 }
490 if (gripBouns.Top.Contains(clientLocation))
491 {
492 m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTTOP;
493 return true;
494 }
495 }
496 else
497 {
498 if (resizableLeft && gripBouns.BottomLeft.Contains(clientLocation))
499 {
500 m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTBOTTOMLEFT;
501 return true;
502 }
503 if (!resizableLeft && gripBouns.BottomRight.Contains(clientLocation))
504 {
505 m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTBOTTOMRIGHT;
506 return true;
507 }
508 if (gripBouns.Bottom.Contains(clientLocation))
509 {
510 m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTBOTTOM;
511 return true;
512 }
513 }
514 if (resizableLeft && gripBouns.Left.Contains(clientLocation))
515 {
516 m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTLEFT;
517 return true;
518 }
519 if (!resizableLeft && gripBouns.Right.Contains(clientLocation))
520 {
521 m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTRIGHT;
522 return true;
523 }
524 return false;
525 }
526
527 private VS.VisualStyleRenderer sizeGripRenderer;
528 /// <summary>
529 /// Paints the sizing grip.
530 /// </summary>
531 /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs" /> instance containing the event data.</param>
532 public void PaintSizeGrip(PaintEventArgs e)
533 {
534 if (e == null || e.Graphics == null || !resizable)
535 {
536 return;
537 }
538 Size clientSize = content.ClientSize;
539 using (Bitmap gripImage = new Bitmap(0x10, 0x10))
540 {
541 using (Graphics g = Graphics.FromImage(gripImage))
542 {
543 if (Application.RenderWithVisualStyles)
544 {
545 if (this.sizeGripRenderer == null)
546 {
547 this.sizeGripRenderer = new VS.VisualStyleRenderer(VS.VisualStyleElement.Status.Gripper.Normal);
548 }
549 this.sizeGripRenderer.DrawBackground(g, new Rectangle(0, 0, 0x10, 0x10));
550 }
551 else
552 {
553 ControlPaint.DrawSizeGrip(g, content.BackColor, 0, 0, 0x10, 0x10);
554 }
555 }
556 GraphicsState gs = e.Graphics.Save();
557 e.Graphics.ResetTransform();
558 if (resizableTop)
559 {
560 if (resizableLeft)
561 {
562 e.Graphics.RotateTransform(180);
563 e.Graphics.TranslateTransform(-clientSize.Width, -clientSize.Height);
564 }
565 else
566 {
567 e.Graphics.ScaleTransform(1, -1);
568 e.Graphics.TranslateTransform(0, -clientSize.Height);
569 }
570 }
571 else if (resizableLeft)
572 {
573 e.Graphics.ScaleTransform(-1, 1);
574 e.Graphics.TranslateTransform(-clientSize.Width, 0);
575 }
576 e.Graphics.DrawImage(gripImage, clientSize.Width - 0x10, clientSize.Height - 0x10 + 1, 0x10, 0x10);
577 e.Graphics.Restore(gs);
578 }
579 }
580
581 #endregion
582 }
583 }
然后新建一个自定义控件,代码如下
1 :
2 using System;
3 using System.Collections.Generic;
4 using System.ComponentModel;
5 using System.Drawing;
6 using System.Data;
7 using System.Linq;
8 using System.Text;
9 using System.Windows.Forms;
10 using System.Collections;
11 using System.Reflection;
12 using Newtonsoft.Json.Linq;
13
14 namespace Controls
15 {
16
17 /// <summary>
18 /// 功能描述:自定义多选下拉框
19 /// 作 者:huangzh
20 /// 创建日期:2016-01-04 11:57:13
21 /// 任务编号:
22 /// </summary>
23 public class ComboBoxEx : ComboBox
24 {
25 PopupForm frmhost;
26 TreeView lst = new TreeView();
27 /// <summary>
28 /// 功能描述:构造方法
29 /// 作 者:huangzh
30 /// 创建日期:2016-01-04 11:57:27
31 /// 任务编号:
32 /// </summary>
33 public ComboBoxEx()
34 {
35 this.DrawMode = DrawMode.OwnerDrawFixed;//只有设置这个属性为OwnerDrawFixed才可能让重画起作用
36
37 lst.Width = ListWidth == 0 ? this.Width : ListWidth;
38 lst.Height = ListHeight == 0 ? 300 : ListHeight;
39 lst.CheckBoxes = true;
40 lst.ShowLines = false;
41 lst.ShowPlusMinus = false;
42 lst.ShowRootLines = false;
43 lst.KeyUp += new KeyEventHandler(lst_KeyUp);
44 lst.AfterCheck += new TreeViewEventHandler(lst_AfterCheck);
45 this.DropDownHeight = 1;
46 frmhost = new PopupForm(lst);
47 //frmhost.Closed += new ToolStripDropDownClosedEventHandler(frmhost_Closed);
48 //frmhost.Opened += new EventHandler(frmhost_Opened);
49 }
50
51 void lst_KeyUp(object sender, KeyEventArgs e)
52 {
53 OnKeyUp(e);
54 }
55
56 void lst_AfterCheck(object sender, TreeViewEventArgs e)
57 {
58 if (e.Node.Checked)
59 {
60 if (Text != "")
61 {
62 Text += ",";
63 }
64 Text += e.Node.Tag.ToString();
65 }
66 else
67 {
68 string strValue = e.Node.Tag.ToString().Trim();
69 if (Text != "")
70 {
71 List<string> strs = Text.Split(',').ToList();
72 strs.Remove("");
73 if (strs.Contains(strValue))
74 {
75 strs.Remove(strValue);
76 Text = string.Join(",", strs);
77 }
78 }
79 }
80 }
81
82 void frmhost_Opened(object sender, EventArgs e)
83 {
84
85 }
86
87 void frmhost_Closed(object sender, ToolStripDropDownClosedEventArgs e)
88 {
89
90 }
91
92 #region Property
93 /// <summary>
94 /// 选中项
95 /// </summary>
96 [Description("选定项的值"), Category("Data")]
97 public List<TreeNode> SelectedItems
98 {
99 get
100 {
101 List<TreeNode> lsttn = new List<TreeNode>();
102 foreach (TreeNode tn in lst.Nodes)
103 {
104 if (tn.Checked)
105 {
106 lsttn.Add(tn);
107 }
108 }
109 return lsttn;
110 }
111 }
112
113 /// <summary>
114 /// 数据源
115 /// </summary>
116 [Description("数据源"), Category("Data")]
117 public new object DataSource
118 {
119 get;
120 set;
121 }
122 /// <summary>
123 /// 显示字段
124 /// </summary>
125 [Description("显示字段"), Category("Data")]
126 public string DisplayFiled
127 {
128 get;
129 set;
130 }
131 /// <summary>
132 /// 值字段
133 /// </summary>
134 [Description("值字段"), Category("Data")]
135 public string ValueFiled
136 {
137 get;
138 set;
139 }
140 /// <summary>
141 /// 列表高度
142 /// </summary>
143 [Description("列表高度"), Category("Data")]
144 public int ListHeight
145 {
146 get;
147 set;
148 }
149
150 /// <summary>
151 /// 列表宽度
152 /// </summary>
153 [Description("列表宽度"), Category("Data")]
154 public int ListWidth
155 {
156 get;
157 set;
158 }
159 #endregion
160
161 /// <summary>
162 /// 功能描述:绑定数据
163 /// 作 者:huangzh
164 /// 创建日期:2016-01-04 10:38:51
165 /// 任务编号:
166 /// </summary>
167 public void DataBind()
168 {
169 this.BeginUpdate();
170 if (DataSource != null)
171 {
172 if (DataSource is IDataReader)
173 {
174 DataTable dataTable = new DataTable();
175 dataTable.Load(DataSource as IDataReader);
176
177 DataBindToDataTable(dataTable);
178 }
179 else if (DataSource is DataView || DataSource is DataSet || DataSource is DataTable)
180 {
181 DataTable dataTable = null;
182
183 if (DataSource is DataView)
184 {
185 dataTable = ((DataView)DataSource).ToTable();
186 }
187 else if (DataSource is DataSet)
188 {
189 dataTable = ((DataSet)DataSource).Tables[0];
190 }
191 else
192 {
193 dataTable = ((DataTable)DataSource);
194 }
195
196 DataBindToDataTable(dataTable);
197 }
198 else if (DataSource is IEnumerable)
199 {
200 DataBindToEnumerable((IEnumerable)DataSource);
201 }
202 else
203 {
204 throw new Exception("DataSource doesn't support data type: " + DataSource.GetType().ToString());
205 }
206 }
207 else
208 {
209 lst.Nodes.Clear();
210 }
211
212 this.EndUpdate();
213 }
214
215 /// <summary>
216 /// 功能描述:绑定Table数据
217 /// 作 者:huangzh
218 /// 创建日期:2016-01-04 10:47:27
219 /// 任务编号:
220 /// </summary>
221 /// <param name="dt">dt</param>
222 private void DataBindToDataTable(DataTable dt)
223 {
224 foreach (DataRow dr in dt.Rows)
225 {
226 TreeNode tn = new TreeNode();
227 if (!string.IsNullOrEmpty(DisplayFiled) && !string.IsNullOrEmpty(ValueFiled))
228 {
229 tn.Text = dr[DisplayFiled].ToString();
230 tn.Tag = dr[ValueFiled].ToString();
231 }
232 else if (string.IsNullOrEmpty(ValueFiled))
233 {
234 tn.Text = dr[DisplayFiled].ToString();
235 tn.Tag = dr[DisplayFiled].ToString();
236 }
237 else if (string.IsNullOrEmpty(DisplayFiled))
238 {
239 tn.Text = dr[ValueFiled].ToString();
240 tn.Tag = dr[ValueFiled].ToString();
241 }
242 else
243 {
244 throw new Exception("ValueFiled和DisplayFiled至少保证有一项有值");
245 }
246 tn.ToolTipText = tn.Text;
247
248 tn.Checked = false;
249 lst.Nodes.Add(tn);
250 }
251 }
252
253 /// <summary>
254 /// 绑定到可枚举类型
255 /// </summary>
256 /// <param name="enumerable">可枚举类型</param>
257 private void DataBindToEnumerable(IEnumerable enumerable)
258 {
259 IEnumerator enumerator = enumerable.GetEnumerator();
260 while (enumerator.MoveNext())
261 {
262 object currentObject = enumerator.Current;
263 lst.Nodes.Add(CreateListItem(currentObject));
264 }
265 }
266
267
268 /// <summary>
269 /// 功能描述:获取一个CheckBox
270 /// 作 者:huangzh
271 /// 创建日期:2016-01-04 10:53:12
272 /// 任务编号:
273 /// </summary>
274 /// <param name="obj">obj</param>
275 /// <returns>返回值</returns>
276 private TreeNode CreateListItem(Object obj)
277 {
278 TreeNode item = new TreeNode();
279
280 if (obj is string)
281 {
282 item.Text = obj.ToString();
283 item.Tag = obj.ToString();
284 }
285 else
286 {
287 if (DisplayFiled != "")
288 {
289 item.Text = GetPropertyValue(obj, DisplayFiled);
290 }
291 else
292 {
293 item.Text = obj.ToString();
294 }
295
296 if (ValueFiled != "")
297 {
298 item.Tag = GetPropertyValue(obj, ValueFiled);
299 }
300 else
301 {
302 item.Tag = obj.ToString();
303 }
304 }
305 item.ToolTipText = item.Text;
306 return item;
307 }
308
309 /// <summary>
310 /// 取得属性值
311 /// </summary>
312 /// <param name="obj"></param>
313 /// <param name="propertyName"></param>
314 private string GetPropertyValue(object obj, string propertyName)
315 {
316 object result = null;
317
318 result = ObjectUtil.GetPropertyValue(obj, propertyName);
319 return result == null ? String.Empty : result.ToString();
320 }
321
322 #region override
323
324 /// <summary>
325 /// 功能描述:OnKeyUp
326 /// 作 者:huangzh
327 /// 创建日期:2016-01-04 11:58:33
328 /// 任务编号:
329 /// </summary>
330 /// <param name="e">e</param>
331 protected override void OnKeyUp(KeyEventArgs e)
332 {
333 base.OnKeyDown(e);
334 bool Pressed = (e.Control && ((e.KeyData & Keys.A) == Keys.A));
335 if (Pressed)
336 {
337 this.Text = "";
338 for (int i = 0; i < lst.Nodes.Count; i++)
339 {
340 lst.Nodes[i].Checked = true;
341 }
342 }
343 }
344
345 /// <summary>
346 /// 功能描述:OnDropDown
347 /// 作 者:huangzh
348 /// 创建日期:2016-01-04 11:58:53
349 /// 任务编号:
350 /// </summary>
351 /// <param name="e">e</param>
352 protected override void OnDropDown(EventArgs e)
353 {
354 this.DroppedDown = false;
355 string strValue = this.Text;
356 if (!string.IsNullOrEmpty(strValue))
357 {
358 List<string> lstvalues = strValue.Split(',').ToList<string>();
359 foreach (TreeNode tn in lst.Nodes)
360 {
361 if (tn.Checked && !lstvalues.Contains(tn.Tag.ToString()) && !string.IsNullOrEmpty(tn.Tag.ToString().Trim()))
362 {
363 tn.Checked = false;
364 }
365 else if (!tn.Checked && lstvalues.Contains(tn.Tag.ToString()) && !string.IsNullOrEmpty(tn.Tag.ToString().Trim()))
366 {
367 tn.Checked = true;
368 }
369 }
370 }
371 else
372 {
373 foreach (TreeNode tn in lst.Nodes)
374 {
375 tn.Checked = false;
376 }
377 }
378 frmhost.Show(this);
379 }
380 #endregion
381 }
382
383
384 /// <summary>
385 /// 对象帮助类
386 /// </summary>
387 public class ObjectUtil
388 {
389 /// <summary>
390 /// 获取对象的属性值
391 /// </summary>
392 /// <param name="obj">可能是DataRowView或一个对象</param>
393 /// <param name="propertyName">属性名</param>
394 /// <returns>属性值</returns>
395 public static object GetPropertyValue(object obj, string propertyName)
396 {
397 object result = null;
398
399 try
400 {
401 if (obj is DataRow)
402 {
403 result = (obj as DataRow)[propertyName];
404 }
405 else if (obj is DataRowView)
406 {
407 result = (obj as DataRowView)[propertyName];
408 }
409 else if (obj is JObject)
410 {
411 result = (obj as JObject).Value<JValue>(propertyName).Value; //.getValue(propertyName);
412 }
413 else
414 {
415 result = GetPropertyValueFormObject(obj, propertyName);
416 }
417 }
418 catch (Exception)
419 {
420 // 找不到此属性
421 }
422
423 return result;
424 }
425
426 /// <summary>
427 /// 获取对象的属性值
428 /// </summary>
429 /// <param name="obj">对象</param>
430 /// <param name="propertyName">属性名("Color"、"BodyStyle"或者"Info.UserName")</param>
431 /// <returns>属性值</returns>
432 private static object GetPropertyValueFormObject(object obj, string propertyName)
433 {
434 object rowObj = obj;
435 object result = null;
436
437 if (propertyName.IndexOf(".") > 0)
438 {
439 string[] properties = propertyName.Split('.');
440 object tmpObj = rowObj;
441
442 for (int i = 0; i < properties.Length; i++)
443 {
444 PropertyInfo property = tmpObj.GetType().GetProperty(properties[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
445 if (property != null)
446 {
447 tmpObj = property.GetValue(tmpObj, null);
448 }
449 }
450
451 result = tmpObj;
452 }
453 else
454 {
455 PropertyInfo property = rowObj.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
456 if (property != null)
457 {
458 result = property.GetValue(rowObj, null);
459 }
460 }
461
462 return result;
463 }
464 }
465 }
然后就是使用了,直接拖一个到界面上,然后设置值就可以了
ListHeight,ListWidth 这两个属性一定要修改下的哦
然后就是绑定数据源
var varSourceFrom = from p in lstEnumEnitty
where p.Type == "source"
select p;
cboSourceFromType.DataSource = varSourceFrom;
cboSourceFromType.DisplayFiled = "Name";
cboSourceFromType.ValueFiled = "Code";
cboSourceFromType.DataBind();
效果就是这样的了
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有