前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >c# 自定义多选下拉列表2

c# 自定义多选下拉列表2

作者头像
冰封一夏
发布2019-09-11 15:28:42
2.8K0
发布2019-09-11 15:28:42
举报

以下为工作中遇到的,备注一下

先需要几个辅助类

代码语言:javascript
复制
  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
代码语言:javascript
复制
  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
代码语言:javascript
复制
  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 }

然后新建一个自定义控件,代码如下

代码语言:javascript
复制
  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 这两个属性一定要修改下的哦

然后就是绑定数据源

代码语言:javascript
复制
  var varSourceFrom = from p in lstEnumEnitty
                                    where p.Type == "source"
                                    select p;
                cboSourceFromType.DataSource = varSourceFrom;
                cboSourceFromType.DisplayFiled = "Name";
                cboSourceFromType.ValueFiled = "Code";
                cboSourceFromType.DataBind();

效果就是这样的了

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-01-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档