c# 自定义多选下拉列表2
以下为工作中遇到的,备注一下
先需要几个辅助类
- #region GripBounds
- using System.Drawing;
- internal struct GripBounds
- {
- private const int GripSize = ;
- private const int CornerGripSize = GripSize << ;
- public GripBounds(Rectangle clientRectangle)
- {
- this.clientRectangle = clientRectangle;
- }
- private Rectangle clientRectangle;
- public Rectangle ClientRectangle
- {
- get { return clientRectangle; }
- //set { clientRectangle = value; }
- }
- public Rectangle Bottom
- {
- get
- {
- Rectangle rect = ClientRectangle;
- rect.Y = rect.Bottom - GripSize + ;
- rect.Height = GripSize;
- return rect;
- }
- }
- public Rectangle BottomRight
- {
- get
- {
- Rectangle rect = ClientRectangle;
- rect.Y = rect.Bottom - CornerGripSize + ;
- rect.Height = CornerGripSize;
- rect.X = rect.Width - CornerGripSize + ;
- rect.Width = CornerGripSize;
- return rect;
- }
- }
- public Rectangle Top
- {
- get
- {
- Rectangle rect = ClientRectangle;
- rect.Height = GripSize;
- return rect;
- }
- }
- public Rectangle TopRight
- {
- get
- {
- Rectangle rect = ClientRectangle;
- rect.Height = CornerGripSize;
- rect.X = rect.Width - CornerGripSize + ;
- rect.Width = CornerGripSize;
- return rect;
- }
- }
- public Rectangle Left
- {
- get
- {
- Rectangle rect = ClientRectangle;
- rect.Width = GripSize;
- return rect;
- }
- }
- public Rectangle BottomLeft
- {
- get
- {
- Rectangle rect = ClientRectangle;
- rect.Width = CornerGripSize;
- rect.Y = rect.Height - CornerGripSize + ;
- rect.Height = CornerGripSize;
- return rect;
- }
- }
- public Rectangle Right
- {
- get
- {
- Rectangle rect = ClientRectangle;
- rect.X = rect.Right - GripSize + ;
- rect.Width = GripSize;
- return rect;
- }
- }
- public Rectangle TopLeft
- {
- get
- {
- Rectangle rect = ClientRectangle;
- rect.Width = CornerGripSize;
- rect.Height = CornerGripSize;
- return rect;
- }
- }
- }
- #endregion
- #region UnsafeMethods
- using System;
- using System.Drawing;
- using System.Runtime.InteropServices;
- internal class UnsafeMethods
- {
- public static readonly IntPtr TRUE = new IntPtr();
- public static readonly IntPtr FALSE = new IntPtr();
- public const int WM_LBUTTONDOWN = 0x201;
- public const int WM_RBUTTONDOWN = 0x204;
- public const int WM_MBUTTONDOWN = 0x207;
- public const int WM_NCLBUTTONDOWN = 0x0A1;
- public const int WM_NCRBUTTONDOWN = 0x0A4;
- public const int WM_NCMBUTTONDOWN = 0x0A7;
- public const int WM_NCCALCSIZE = 0x0083;
- public const int WM_NCHITTEST = 0x0084;
- public const int WM_NCPAINT = 0x0085;
- public const int WM_NCACTIVATE = 0x0086;
- public const int WM_MOUSELEAVE = 0x02A3;
- public const int WS_EX_NOACTIVATE = 0x08000000;
- public const int HTTRANSPARENT = -;
- public const int HTLEFT = ;
- public const int HTRIGHT = ;
- public const int HTTOP = ;
- public const int HTTOPLEFT = ;
- public const int HTTOPRIGHT = ;
- public const int HTBOTTOM = ;
- public const int HTBOTTOMLEFT = ;
- public const int HTBOTTOMRIGHT = ;
- public const int WM_USER = 0x0400;
- public const int WM_REFLECT = WM_USER + 0x1C00;
- public const int WM_COMMAND = 0x0111;
- public const int CBN_DROPDOWN = ;
- public const int WM_GETMINMAXINFO = 0x0024;
- public enum TrackerEventFlags : uint
- {
- TME_HOVER = 0x00000001,
- TME_LEAVE = 0x00000002,
- TME_QUERY = 0x40000000,
- TME_CANCEL = 0x80000000
- }
- [DllImport("user32.dll")]
- public static extern IntPtr GetWindowDC(IntPtr hWnd);
- [DllImport("user32.dll")]
- public static extern int ReleaseDC(IntPtr hwnd, IntPtr hDC);
- [DllImport("user32")]
- public static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack);
- [DllImport("user32.dll")]
- public static extern bool SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
- internal static int HIWORD(int n)
- {
- return (n >> ) & 0xffff;
- }
- internal static int HIWORD(IntPtr n)
- {
- return HIWORD(unchecked((int)(long)n));
- }
- internal static int LOWORD(int n)
- {
- return n & 0xffff;
- }
- internal static int LOWORD(IntPtr n)
- {
- return LOWORD(unchecked((int)(long)n));
- }
- [StructLayout(LayoutKind.Sequential)]
- internal struct TRACKMOUSEEVENT
- {
- public uint cbSize;
- public uint dwFlags;
- public IntPtr hwndTrack;
- public uint dwHoverTime;
- }
- [StructLayout(LayoutKind.Sequential)]
- internal struct MINMAXINFO
- {
- public Point reserved;
- public Size maxSize;
- public Point maxPosition;
- public Size minTrackSize;
- public Size maxTrackSize;
- }
- #region RECT structure
- [StructLayout(LayoutKind.Sequential)]
- internal struct RECT
- {
- public int left;
- public int top;
- public int right;
- public int bottom;
- public RECT(int left, int top, int right, int bottom)
- {
- this.left = left;
- this.top = top;
- this.right = right;
- this.bottom = bottom;
- }
- public Rectangle Rect
- {
- get
- {
- return new Rectangle(
- this.left,
- this.top,
- this.right - this.left,
- this.bottom - this.top);
- }
- }
- public static RECT FromXYWH(int x, int y, int width, int height)
- {
- return new RECT(x,
- y,
- x + width,
- y + height);
- }
- public static RECT FromRectangle(Rectangle rect)
- {
- return new RECT(rect.Left,
- rect.Top,
- rect.Right,
- rect.Bottom);
- }
- }
- #endregion RECT structure
- #region WINDOWPOS
- [StructLayout(LayoutKind.Sequential)]
- internal struct WINDOWPOS
- {
- internal IntPtr hwnd;
- internal IntPtr hWndInsertAfter;
- internal int x;
- internal int y;
- internal int cx;
- internal int cy;
- internal uint flags;
- }
- #endregion
- #region NCCALCSIZE_PARAMS
- //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowstructures/nccalcsize_params.asp
- [StructLayout(LayoutKind.Sequential)]
- public struct NCCALCSIZE_PARAMS
- {
- /// <summary>
- /// Contains the new coordinates of a window that has been moved or resized, that is, it is the proposed new window coordinates.
- /// </summary>
- public RECT rectProposed;
- /// <summary>
- /// Contains the coordinates of the window before it was moved or resized.
- /// </summary>
- public RECT rectBeforeMove;
- /// <summary>
- /// Contains the coordinates of the window's client area before the window was moved or resized.
- /// </summary>
- public RECT rectClientBeforeMove;
- /// <summary>
- /// Pointer to a WINDOWPOS structure that contains the size and position values specified in the operation that moved or resized the window.
- /// </summary>
- public WINDOWPOS lpPos;
- }
- #endregion
- }
- #endregion
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Text;
- using System.Windows.Forms;
- using System.Security.Permissions;
- using System.Runtime.InteropServices;
- using VS = System.Windows.Forms.VisualStyles;
- /*
- <li>Base class for custom tooltips.</li>
- <li>Office-2007-like tooltip class.</li>
- */
- namespace ZhuoYueE.Bpc.Controls
- {
- /// <summary>
- /// Represents a pop-up window.
- /// </summary>
- [ToolboxItem(false)]
- public partial class PopupForm : ToolStripDropDown
- {
- #region " Fields & Properties "
- private Control content;
- /// <summary>
- /// Gets the content of the pop-up.
- /// </summary>
- public Control Content
- {
- get { return content; }
- }
- private bool fade;
- /// <summary>
- /// Gets a value indicating whether the <see cref="PopupControl.Popup"/> uses the fade effect.
- /// </summary>
- /// <value><c>true</c> if pop-up uses the fade effect; otherwise, <c>false</c>.</value>
- /// <remarks>To use the fade effect, the FocusOnOpen property also has to be set to <c>true</c>.</remarks>
- public bool UseFadeEffect
- {
- get { return fade; }
- set
- {
- if (fade == value) return;
- fade = value;
- }
- }
- private bool focusOnOpen = true;
- /// <summary>
- /// Gets or sets a value indicating whether the content should receive the focus after the pop-up has been opened.
- /// </summary>
- /// <value><c>true</c> if the content should be focused after the pop-up has been opened; otherwise, <c>false</c>.</value>
- /// <remarks>If the FocusOnOpen property is set to <c>false</c>, then pop-up cannot use the fade effect.</remarks>
- public bool FocusOnOpen
- {
- get { return focusOnOpen; }
- set { focusOnOpen = value; }
- }
- private bool acceptAlt = true;
- /// <summary>
- /// Gets or sets a value indicating whether presing the alt key should close the pop-up.
- /// </summary>
- /// <value><c>true</c> if presing the alt key does not close the pop-up; otherwise, <c>false</c>.</value>
- public bool AcceptAlt
- {
- get { return acceptAlt; }
- set { acceptAlt = value; }
- }
- private PopupForm ownerPopup;
- private PopupForm childPopup;
- private bool _resizable;
- private bool resizable;
- /// <summary>
- /// Gets or sets a value indicating whether the <see cref="PopupControl.Popup" /> is resizable.
- /// </summary>
- /// <value><c>true</c> if resizable; otherwise, <c>false</c>.</value>
- public bool Resizable
- {
- get { return resizable && _resizable; }
- set { resizable = value; }
- }
- private ToolStripControlHost host;
- private Size minSize;
- /// <summary>
- /// Gets or sets a minimum size of the pop-up.
- /// </summary>
- /// <returns>An ordered pair of type <see cref="T:System.Drawing.Size" /> representing the width and height of a rectangle.</returns>
- public new Size MinimumSize
- {
- get { return minSize; }
- set { minSize = value; }
- }
- private Size maxSize;
- /// <summary>
- /// Gets or sets a maximum size of the pop-up.
- /// </summary>
- /// <returns>An ordered pair of type <see cref="T:System.Drawing.Size" /> representing the width and height of a rectangle.</returns>
- public new Size MaximumSize
- {
- get { return maxSize; }
- set { maxSize = value; }
- }
- private bool _isOpen;
- public bool IsOpen
- {
- get { return _isOpen; }
- }
- /// <summary>
- /// Gets parameters of a new window.
- /// </summary>
- /// <returns>An object of type <see cref="T:System.Windows.Forms.CreateParams" /> used when creating a new window.</returns>
- protected override CreateParams CreateParams
- {
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- get
- {
- CreateParams cp = base.CreateParams;
- cp.ExStyle |= UnsafeMethods.WS_EX_NOACTIVATE;
- return cp;
- }
- }
- #endregion
- #region " Constructors "
- /// <summary>
- /// Initializes a new instance of the <see cref="PopupControl.Popup"/> class.
- /// </summary>
- /// <param name="content">The content of the pop-up.</param>
- /// <remarks>
- /// Pop-up will be disposed immediately after disposion of the content control.
- /// </remarks>
- /// <exception cref="T:System.ArgumentNullException"><paramref name="content" /> is <code>null</code>.</exception>
- public PopupForm(Control content)
- {
- if (content == null)
- {
- throw new ArgumentNullException("content");
- }
- this.content = content;
- this.fade = SystemInformation.IsMenuAnimationEnabled && SystemInformation.IsMenuFadeEnabled;
- this._resizable = true;
- AutoSize = false;
- DoubleBuffered = true;
- ResizeRedraw = true;
- host = new ToolStripControlHost(content);
- Padding = Margin = host.Padding = host.Margin = Padding.Empty;
- MinimumSize = content.MinimumSize;
- content.MinimumSize = content.Size;
- MaximumSize = content.MaximumSize;
- content.MaximumSize = content.Size;
- Size = content.Size;
- content.Location = Point.Empty;
- Items.Add(host);
- content.Disposed += delegate(object sender, EventArgs e)
- {
- content = null;
- Dispose(true);
- };
- content.RegionChanged += delegate(object sender, EventArgs e)
- {
- UpdateRegion();
- };
- content.Paint += delegate(object sender, PaintEventArgs e)
- {
- PaintSizeGrip(e);
- };
- UpdateRegion();
- }
- #endregion
- #region " Methods "
- /// <summary>
- /// Processes a dialog box key.
- /// </summary>
- /// <param name="keyData">One of the <see cref="T:System.Windows.Forms.Keys" /> values that represents the key to process.</param>
- /// <returns>
- /// true if the key was processed by the control; otherwise, false.
- /// </returns>
- protected override bool ProcessDialogKey(Keys keyData)
- {
- if (acceptAlt && ((keyData & Keys.Alt) == Keys.Alt))
- {
- if ((keyData & Keys.F4) != Keys.F4)
- {
- return false;
- }
- else
- {
- this.Close();
- }
- }
- return base.ProcessDialogKey(keyData);
- }
- /// <summary>
- /// Updates the pop-up region.
- /// </summary>
- protected void UpdateRegion()
- {
- if (this.Region != null)
- {
- this.Region.Dispose();
- this.Region = null;
- }
- if (content.Region != null)
- {
- this.Region = content.Region.Clone();
- }
- }
- /// <summary>
- /// Shows the pop-up window below the specified control.
- /// </summary>
- /// <param name="control">The control below which the pop-up will be shown.</param>
- /// <remarks>
- /// When there is no space below the specified control, the pop-up control is shown above it.
- /// </remarks>
- /// <exception cref="T:System.ArgumentNullException"><paramref name="control"/> is <code>null</code>.</exception>
- public void Show(Control control)
- {
- Show(control, control.ClientRectangle);
- }
- public void Show(Control control, bool center)
- {
- Show(control, control.ClientRectangle, center);
- }
- /// <summary>
- /// Shows the pop-up window below the specified area of the specified control.
- /// </summary>
- /// <param name="control">The control used to compute screen location of specified area.</param>
- /// <param name="area">The area of control below which the pop-up will be shown.</param>
- /// <remarks>
- /// When there is no space below specified area, the pop-up control is shown above it.
- /// </remarks>
- /// <exception cref="T:System.ArgumentNullException"><paramref name="control"/> is <code>null</code>.</exception>
- public void Show(Control control, Rectangle area)
- {
- Show(control, area, false);
- }
- public void Show(Control control, Rectangle area, bool center)
- {
- if (control == null)
- {
- throw new ArgumentNullException("control");
- }
- SetOwnerItem(control);
- resizableTop = resizableLeft = false;
- Point location = control.PointToScreen(new Point(area.Left, area.Top + area.Height));
- Rectangle screen = Screen.FromControl(control).WorkingArea;
- if (center)
- {
- if (location.X + (area.Width + Size.Width) / > screen.Right)
- {
- resizableLeft = true;
- location.X = screen.Right - Size.Width;
- }
- else
- {
- resizableLeft = true;
- location.X = location.X - (Size.Width - area.Width) / ;
- }
- }
- else
- {
- if (location.X + Size.Width > (screen.Left + screen.Width))
- {
- resizableLeft = true;
- location.X = (screen.Left + screen.Width) - Size.Width;
- }
- }
- if (location.Y + Size.Height > (screen.Top + screen.Height))
- {
- resizableTop = true;
- location.Y -= Size.Height + area.Height;
- }
- location = control.PointToClient(location);
- Show(control, location, ToolStripDropDownDirection.BelowRight);
- }
- private const int frames = ;
- private const int totalduration = ;
- private const int frameduration = totalduration / frames;
- /// <summary>
- /// 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.
- /// </summary>
- /// <param name="visible">true if the owner <see cref="T:System.Windows.Forms.ToolStrip" /> is currently displayed; otherwise, false.</param>
- protected override void SetVisibleCore(bool visible)
- {
- double opacity = Opacity;
- if (visible && fade && focusOnOpen) Opacity = ;
- base.SetVisibleCore(visible);
- if (!visible || !fade || !focusOnOpen) return;
- for (int i = ; i <= frames; i++)
- {
- if (i > )
- {
- System.Threading.Thread.Sleep(frameduration);
- }
- Opacity = opacity * (double)i / (double)frames;
- }
- Opacity = opacity;
- }
- private bool resizableTop;
- private bool resizableLeft;
- private void SetOwnerItem(Control control)
- {
- if (control == null)
- {
- return;
- }
- if (control is PopupForm)
- {
- PopupForm popupControl = control as PopupForm;
- ownerPopup = popupControl;
- ownerPopup.childPopup = this;
- OwnerItem = popupControl.Items[];
- return;
- }
- if (control.Parent != null)
- {
- SetOwnerItem(control.Parent);
- }
- }
- /// <summary>
- /// Raises the <see cref="E:System.Windows.Forms.Control.SizeChanged" /> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
- protected override void OnSizeChanged(EventArgs e)
- {
- content.MinimumSize = Size;
- content.MaximumSize = Size;
- content.Size = Size;
- content.Location = Point.Empty;
- base.OnSizeChanged(e);
- }
- /// <summary>
- /// Raises the <see cref="E:System.Windows.Forms.ToolStripDropDown.Opening" /> event.
- /// </summary>
- /// <param name="e">A <see cref="T:System.ComponentModel.CancelEventArgs" /> that contains the event data.</param>
- protected override void OnOpening(CancelEventArgs e)
- {
- if (content.IsDisposed || content.Disposing)
- {
- e.Cancel = true;
- return;
- }
- UpdateRegion();
- base.OnOpening(e);
- }
- /// <summary>
- /// Raises the <see cref="E:System.Windows.Forms.ToolStripDropDown.Opened" /> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
- protected override void OnOpened(EventArgs e)
- {
- if (ownerPopup != null)
- {
- ownerPopup._resizable = false;
- }
- if (focusOnOpen)
- {
- content.Focus();
- }
- _isOpen = true;
- base.OnOpened(e);
- }
- /// <summary>
- /// Raises the <see cref="E:System.Windows.Forms.ToolStripDropDown.Closed"/> event.
- /// </summary>
- /// <param name="e">A <see cref="T:System.Windows.Forms.ToolStripDropDownClosedEventArgs"/> that contains the event data.</param>
- protected override void OnClosed(ToolStripDropDownClosedEventArgs e)
- {
- if (ownerPopup != null)
- {
- ownerPopup._resizable = true;
- }
- _isOpen = false;
- base.OnClosed(e);
- }
- #endregion
- #region " Resizing Support "
- /// <summary>
- /// Processes Windows messages.
- /// </summary>
- /// <param name="m">The Windows <see cref="T:System.Windows.Forms.Message" /> to process.</param>
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- protected override void WndProc(ref Message m)
- {
- if (InternalProcessResizing(ref m, false))
- {
- return;
- }
- base.WndProc(ref m);
- }
- /// <summary>
- /// Processes the resizing messages.
- /// </summary>
- /// <param name="m">The message.</param>
- /// <returns>true, if the WndProc method from the base class shouldn't be invoked.</returns>
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public bool ProcessResizing(ref Message m)
- {
- return InternalProcessResizing(ref m, true);
- }
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- private bool InternalProcessResizing(ref Message m, bool contentControl)
- {
- if (m.Msg == UnsafeMethods.WM_NCACTIVATE && m.WParam != IntPtr.Zero && childPopup != null && childPopup.Visible)
- {
- childPopup.Hide();
- }
- if (!Resizable)
- {
- return false;
- }
- if (m.Msg == UnsafeMethods.WM_NCHITTEST)
- {
- return OnNcHitTest(ref m, contentControl);
- }
- else if (m.Msg == UnsafeMethods.WM_GETMINMAXINFO)
- {
- return OnGetMinMaxInfo(ref m);
- }
- return false;
- }
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- private bool OnGetMinMaxInfo(ref Message m)
- {
- UnsafeMethods.MINMAXINFO minmax = (UnsafeMethods.MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(UnsafeMethods.MINMAXINFO));
- minmax.maxTrackSize = this.MaximumSize;
- minmax.minTrackSize = this.MinimumSize;
- Marshal.StructureToPtr(minmax, m.LParam, false);
- return true;
- }
- private bool OnNcHitTest(ref Message m, bool contentControl)
- {
- int x = UnsafeMethods.LOWORD(m.LParam);
- int y = UnsafeMethods.HIWORD(m.LParam);
- Point clientLocation = PointToClient(new Point(x, y));
- GripBounds gripBouns = new GripBounds(contentControl ? content.ClientRectangle : ClientRectangle);
- IntPtr transparent = new IntPtr(UnsafeMethods.HTTRANSPARENT);
- if (resizableTop)
- {
- if (resizableLeft && gripBouns.TopLeft.Contains(clientLocation))
- {
- m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTTOPLEFT;
- return true;
- }
- if (!resizableLeft && gripBouns.TopRight.Contains(clientLocation))
- {
- m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTTOPRIGHT;
- return true;
- }
- if (gripBouns.Top.Contains(clientLocation))
- {
- m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTTOP;
- return true;
- }
- }
- else
- {
- if (resizableLeft && gripBouns.BottomLeft.Contains(clientLocation))
- {
- m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTBOTTOMLEFT;
- return true;
- }
- if (!resizableLeft && gripBouns.BottomRight.Contains(clientLocation))
- {
- m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTBOTTOMRIGHT;
- return true;
- }
- if (gripBouns.Bottom.Contains(clientLocation))
- {
- m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTBOTTOM;
- return true;
- }
- }
- if (resizableLeft && gripBouns.Left.Contains(clientLocation))
- {
- m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTLEFT;
- return true;
- }
- if (!resizableLeft && gripBouns.Right.Contains(clientLocation))
- {
- m.Result = contentControl ? transparent : (IntPtr)UnsafeMethods.HTRIGHT;
- return true;
- }
- return false;
- }
- private VS.VisualStyleRenderer sizeGripRenderer;
- /// <summary>
- /// Paints the sizing grip.
- /// </summary>
- /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs" /> instance containing the event data.</param>
- public void PaintSizeGrip(PaintEventArgs e)
- {
- if (e == null || e.Graphics == null || !resizable)
- {
- return;
- }
- Size clientSize = content.ClientSize;
- using (Bitmap gripImage = new Bitmap(0x10, 0x10))
- {
- using (Graphics g = Graphics.FromImage(gripImage))
- {
- if (Application.RenderWithVisualStyles)
- {
- if (this.sizeGripRenderer == null)
- {
- this.sizeGripRenderer = new VS.VisualStyleRenderer(VS.VisualStyleElement.Status.Gripper.Normal);
- }
- this.sizeGripRenderer.DrawBackground(g, new Rectangle(, , 0x10, 0x10));
- }
- else
- {
- ControlPaint.DrawSizeGrip(g, content.BackColor, , , 0x10, 0x10);
- }
- }
- GraphicsState gs = e.Graphics.Save();
- e.Graphics.ResetTransform();
- if (resizableTop)
- {
- if (resizableLeft)
- {
- e.Graphics.RotateTransform();
- e.Graphics.TranslateTransform(-clientSize.Width, -clientSize.Height);
- }
- else
- {
- e.Graphics.ScaleTransform(, -);
- e.Graphics.TranslateTransform(, -clientSize.Height);
- }
- }
- else if (resizableLeft)
- {
- e.Graphics.ScaleTransform(-, );
- e.Graphics.TranslateTransform(-clientSize.Width, );
- }
- e.Graphics.DrawImage(gripImage, clientSize.Width - 0x10, clientSize.Height - 0x10 + , 0x10, 0x10);
- e.Graphics.Restore(gs);
- }
- }
- #endregion
- }
- }
然后新建一个自定义控件,代码如下
- :
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Data;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.Collections;
- using System.Reflection;
- using Newtonsoft.Json.Linq;
- namespace Controls
- {
- /// <summary>
- /// 功能描述:自定义多选下拉框
- /// 作 者:huangzh
- /// 创建日期:2016-01-04 11:57:13
- /// 任务编号:
- /// </summary>
- public class ComboBoxEx : ComboBox
- {
- PopupForm frmhost;
- TreeView lst = new TreeView();
- /// <summary>
- /// 功能描述:构造方法
- /// 作 者:huangzh
- /// 创建日期:2016-01-04 11:57:27
- /// 任务编号:
- /// </summary>
- public ComboBoxEx()
- {
- this.DrawMode = DrawMode.OwnerDrawFixed;//只有设置这个属性为OwnerDrawFixed才可能让重画起作用
- lst.Width = ListWidth == ? this.Width : ListWidth;
- lst.Height = ListHeight == ? : ListHeight;
- lst.CheckBoxes = true;
- lst.ShowLines = false;
- lst.ShowPlusMinus = false;
- lst.ShowRootLines = false;
- lst.KeyUp += new KeyEventHandler(lst_KeyUp);
- lst.AfterCheck += new TreeViewEventHandler(lst_AfterCheck);
- this.DropDownHeight = ;
- frmhost = new PopupForm(lst);
- //frmhost.Closed += new ToolStripDropDownClosedEventHandler(frmhost_Closed);
- //frmhost.Opened += new EventHandler(frmhost_Opened);
- }
- void lst_KeyUp(object sender, KeyEventArgs e)
- {
- OnKeyUp(e);
- }
- void lst_AfterCheck(object sender, TreeViewEventArgs e)
- {
- if (e.Node.Checked)
- {
- if (Text != "")
- {
- Text += ",";
- }
- Text += e.Node.Tag.ToString();
- }
- else
- {
- string strValue = e.Node.Tag.ToString().Trim();
- if (Text != "")
- {
- List<string> strs = Text.Split(',').ToList();
- strs.Remove("");
- if (strs.Contains(strValue))
- {
- strs.Remove(strValue);
- Text = string.Join(",", strs);
- }
- }
- }
- }
- void frmhost_Opened(object sender, EventArgs e)
- {
- }
- void frmhost_Closed(object sender, ToolStripDropDownClosedEventArgs e)
- {
- }
- #region Property
- /// <summary>
- /// 选中项
- /// </summary>
- [Description("选定项的值"), Category("Data")]
- public List<TreeNode> SelectedItems
- {
- get
- {
- List<TreeNode> lsttn = new List<TreeNode>();
- foreach (TreeNode tn in lst.Nodes)
- {
- if (tn.Checked)
- {
- lsttn.Add(tn);
- }
- }
- return lsttn;
- }
- }
- /// <summary>
- /// 数据源
- /// </summary>
- [Description("数据源"), Category("Data")]
- public new object DataSource
- {
- get;
- set;
- }
- /// <summary>
- /// 显示字段
- /// </summary>
- [Description("显示字段"), Category("Data")]
- public string DisplayFiled
- {
- get;
- set;
- }
- /// <summary>
- /// 值字段
- /// </summary>
- [Description("值字段"), Category("Data")]
- public string ValueFiled
- {
- get;
- set;
- }
- /// <summary>
- /// 列表高度
- /// </summary>
- [Description("列表高度"), Category("Data")]
- public int ListHeight
- {
- get;
- set;
- }
- /// <summary>
- /// 列表宽度
- /// </summary>
- [Description("列表宽度"), Category("Data")]
- public int ListWidth
- {
- get;
- set;
- }
- #endregion
- /// <summary>
- /// 功能描述:绑定数据
- /// 作 者:huangzh
- /// 创建日期:2016-01-04 10:38:51
- /// 任务编号:
- /// </summary>
- public void DataBind()
- {
- this.BeginUpdate();
- if (DataSource != null)
- {
- if (DataSource is IDataReader)
- {
- DataTable dataTable = new DataTable();
- dataTable.Load(DataSource as IDataReader);
- DataBindToDataTable(dataTable);
- }
- else if (DataSource is DataView || DataSource is DataSet || DataSource is DataTable)
- {
- DataTable dataTable = null;
- if (DataSource is DataView)
- {
- dataTable = ((DataView)DataSource).ToTable();
- }
- else if (DataSource is DataSet)
- {
- dataTable = ((DataSet)DataSource).Tables[];
- }
- else
- {
- dataTable = ((DataTable)DataSource);
- }
- DataBindToDataTable(dataTable);
- }
- else if (DataSource is IEnumerable)
- {
- DataBindToEnumerable((IEnumerable)DataSource);
- }
- else
- {
- throw new Exception("DataSource doesn't support data type: " + DataSource.GetType().ToString());
- }
- }
- else
- {
- lst.Nodes.Clear();
- }
- this.EndUpdate();
- }
- /// <summary>
- /// 功能描述:绑定Table数据
- /// 作 者:huangzh
- /// 创建日期:2016-01-04 10:47:27
- /// 任务编号:
- /// </summary>
- /// <param name="dt">dt</param>
- private void DataBindToDataTable(DataTable dt)
- {
- foreach (DataRow dr in dt.Rows)
- {
- TreeNode tn = new TreeNode();
- if (!string.IsNullOrEmpty(DisplayFiled) && !string.IsNullOrEmpty(ValueFiled))
- {
- tn.Text = dr[DisplayFiled].ToString();
- tn.Tag = dr[ValueFiled].ToString();
- }
- else if (string.IsNullOrEmpty(ValueFiled))
- {
- tn.Text = dr[DisplayFiled].ToString();
- tn.Tag = dr[DisplayFiled].ToString();
- }
- else if (string.IsNullOrEmpty(DisplayFiled))
- {
- tn.Text = dr[ValueFiled].ToString();
- tn.Tag = dr[ValueFiled].ToString();
- }
- else
- {
- throw new Exception("ValueFiled和DisplayFiled至少保证有一项有值");
- }
- tn.ToolTipText = tn.Text;
- tn.Checked = false;
- lst.Nodes.Add(tn);
- }
- }
- /// <summary>
- /// 绑定到可枚举类型
- /// </summary>
- /// <param name="enumerable">可枚举类型</param>
- private void DataBindToEnumerable(IEnumerable enumerable)
- {
- IEnumerator enumerator = enumerable.GetEnumerator();
- while (enumerator.MoveNext())
- {
- object currentObject = enumerator.Current;
- lst.Nodes.Add(CreateListItem(currentObject));
- }
- }
- /// <summary>
- /// 功能描述:获取一个CheckBox
- /// 作 者:huangzh
- /// 创建日期:2016-01-04 10:53:12
- /// 任务编号:
- /// </summary>
- /// <param name="obj">obj</param>
- /// <returns>返回值</returns>
- private TreeNode CreateListItem(Object obj)
- {
- TreeNode item = new TreeNode();
- if (obj is string)
- {
- item.Text = obj.ToString();
- item.Tag = obj.ToString();
- }
- else
- {
- if (DisplayFiled != "")
- {
- item.Text = GetPropertyValue(obj, DisplayFiled);
- }
- else
- {
- item.Text = obj.ToString();
- }
- if (ValueFiled != "")
- {
- item.Tag = GetPropertyValue(obj, ValueFiled);
- }
- else
- {
- item.Tag = obj.ToString();
- }
- }
- item.ToolTipText = item.Text;
- return item;
- }
- /// <summary>
- /// 取得属性值
- /// </summary>
- /// <param name="obj"></param>
- /// <param name="propertyName"></param>
- private string GetPropertyValue(object obj, string propertyName)
- {
- object result = null;
- result = ObjectUtil.GetPropertyValue(obj, propertyName);
- return result == null ? String.Empty : result.ToString();
- }
- #region override
- /// <summary>
- /// 功能描述:OnKeyUp
- /// 作 者:huangzh
- /// 创建日期:2016-01-04 11:58:33
- /// 任务编号:
- /// </summary>
- /// <param name="e">e</param>
- protected override void OnKeyUp(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- bool Pressed = (e.Control && ((e.KeyData & Keys.A) == Keys.A));
- if (Pressed)
- {
- this.Text = "";
- for (int i = ; i < lst.Nodes.Count; i++)
- {
- lst.Nodes[i].Checked = true;
- }
- }
- }
- /// <summary>
- /// 功能描述:OnDropDown
- /// 作 者:huangzh
- /// 创建日期:2016-01-04 11:58:53
- /// 任务编号:
- /// </summary>
- /// <param name="e">e</param>
- protected override void OnDropDown(EventArgs e)
- {
- this.DroppedDown = false;
- string strValue = this.Text;
- if (!string.IsNullOrEmpty(strValue))
- {
- List<string> lstvalues = strValue.Split(',').ToList<string>();
- foreach (TreeNode tn in lst.Nodes)
- {
- if (tn.Checked && !lstvalues.Contains(tn.Tag.ToString()) && !string.IsNullOrEmpty(tn.Tag.ToString().Trim()))
- {
- tn.Checked = false;
- }
- else if (!tn.Checked && lstvalues.Contains(tn.Tag.ToString()) && !string.IsNullOrEmpty(tn.Tag.ToString().Trim()))
- {
- tn.Checked = true;
- }
- }
- }
- else
- {
- foreach (TreeNode tn in lst.Nodes)
- {
- tn.Checked = false;
- }
- }
- frmhost.Show(this);
- }
- #endregion
- }
- /// <summary>
- /// 对象帮助类
- /// </summary>
- public class ObjectUtil
- {
- /// <summary>
- /// 获取对象的属性值
- /// </summary>
- /// <param name="obj">可能是DataRowView或一个对象</param>
- /// <param name="propertyName">属性名</param>
- /// <returns>属性值</returns>
- public static object GetPropertyValue(object obj, string propertyName)
- {
- object result = null;
- try
- {
- if (obj is DataRow)
- {
- result = (obj as DataRow)[propertyName];
- }
- else if (obj is DataRowView)
- {
- result = (obj as DataRowView)[propertyName];
- }
- else if (obj is JObject)
- {
- result = (obj as JObject).Value<JValue>(propertyName).Value; //.getValue(propertyName);
- }
- else
- {
- result = GetPropertyValueFormObject(obj, propertyName);
- }
- }
- catch (Exception)
- {
- // 找不到此属性
- }
- return result;
- }
- /// <summary>
- /// 获取对象的属性值
- /// </summary>
- /// <param name="obj">对象</param>
- /// <param name="propertyName">属性名("Color"、"BodyStyle"或者"Info.UserName")</param>
- /// <returns>属性值</returns>
- private static object GetPropertyValueFormObject(object obj, string propertyName)
- {
- object rowObj = obj;
- object result = null;
- if (propertyName.IndexOf(".") > )
- {
- string[] properties = propertyName.Split('.');
- object tmpObj = rowObj;
- for (int i = ; i < properties.Length; i++)
- {
- PropertyInfo property = tmpObj.GetType().GetProperty(properties[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- if (property != null)
- {
- tmpObj = property.GetValue(tmpObj, null);
- }
- }
- result = tmpObj;
- }
- else
- {
- PropertyInfo property = rowObj.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- if (property != null)
- {
- result = property.GetValue(rowObj, null);
- }
- }
- return result;
- }
- }
- }
然后就是使用了,直接拖一个到界面上,然后设置值就可以了
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();
效果就是这样的了
需要引用的一个DLL去我的上一个文章里面下载吧
c# 自定义多选下拉列表2的更多相关文章
- Flex4 双选下拉列表的实现(源代码)
本文属原创文章,如需转载,请注明出处,谢谢 企业应用中少不了双选下拉列表控件,但几乎都没有独立的控件,Flex在这上面得天独厚,ArrayCollection的过滤功能使得我们只需要一个数据源就可以将 ...
- WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 下拉选 ...
- 一款不错的多选下拉列表利器—— Ext.ux.form.SuperBoxSelect
在B/S系统中,下拉列表(select/dropdownlist/combobox)的应用随处可见,为了增强用户体验,开发人员也常常会做一些带联想功能的下拉列表, 特别是数据项比较多的时候,用户筛选起 ...
- 【转】WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: 下拉选择控件ComboBox的自定义样式及扩展: 自定义多选控件Mul ...
- WPF 自定义ComboBox样式,自定义多选控件
原文:WPF 自定义ComboBox样式,自定义多选控件 一.ComboBox基本样式 ComboBox有两种状态,可编辑和不可编辑状态.通过设置IsEditable属性可以切换控件状态. 先看基本样 ...
- 自定义SWT控件二之自定义多选下拉框
2.自定义下拉多选框 package com.view.control.select; import java.util.ArrayList; import java.util.HashMap; im ...
- javascript操作多选下拉列表
闲来无事,把javascript操作多选下拉列表有关的操作知识复习了一遍,代码附上 <%-- Created by IntelliJ IDEA. User: Administrator Date ...
- kendoUI 多选下拉列表 kendoMultiSelect
问题1:被重复渲染 点击新增按钮----弹出模态框 多选下拉列表在多选框中只是初始化过一次.但是每次点击新增后 发现 多选下拉列表 被重复渲染了 解决方案 在 新增时 先将其父元素div中 的s ...
- 如何对tableview进行自定义多选
前言: 很多入门不久的程序员或许都会遇到系统自带的tableview多选时cell选择时不能选择自己想要的点击时的颜色或者图片,这让初级开发者们很烦恼.今天,我试着花了几个小时的时间用了自己的想法,去 ...
随机推荐
- oracle 11g 自己主动调整
--:自己主动调教计划 begin dbms_workload_repository.create_snapshot(); end; select /*+ result_cache */ coun ...
- Android开发之控制Toast的开启与关闭
开发这个程序之前先解释一下,为什么Toast信息提示框在显示一定时间后会自己主动消失?由于在Android系统中有一个Toast队列,系统会依次从这个队列中取出一个Toast,并显示它.在显示了指定时 ...
- c语言复杂声明解析
这是个好东西,接触c语言好几年了,第一次看到这东西,惊喜万分. 先提供个分析案例,以后看方便 vector <int> * (*seq_array[]) (int )={func1,fun ...
- Hack 语言学习/参考---1.Hack 语言
Table of Contents What is Hack? Hack Background Summary Hack is a language for HHVM that interopates ...
- windows socket 网络编程
样例代码就在我的博客中,包含六个UDP和TCP发送接受的cpp文件,一个基于MFC的局域网聊天小工具project,和此小工具的全部执行时库.资源和执行程序.代码的压缩包位置是http://www.b ...
- 多线程学习之三生产者消费者模式Guarded Suspension
Guarded Suspension[生产消费者模式] 一:guarded suspension的参与者--->guardedObject(被防卫)参与者 1.1该 ...
- DateTime.ToString("dd/MM/yyyy");后,不能直接Convert.ToDateTime的解决:
原文:DateTime.ToString("dd/MM/yyyy");后,不能直接Convert.ToDateTime的解决: DateTime.ToString("dd ...
- ADS-B 雷达 显示终端5.8
改动日志 1 更新背景地图. 增加了全国范围内的国际航路.区域航路信息,全部航路信息来自网络及中国民用航空局公布的公开资料:航路採用深蓝色画笔绘制航路中包括有航路代码.高度及报告点信息.代码及报告点 ...
- 关于s2sh框架关于hibernate懒加载问题的说明和解决方案
首先我们来看下面这个图,解释了一个web程序的一次请求流程! 懒加载异常的说明: 懒加载就是我们在查询一个对象时,它所有的属性是否要被查出来! 如果懒加载开启的话,session在service层就被 ...
- 74LS183 加法器 【数字电路】
74LS183 搭的一个还有点意思的加法电路,串行进位的 2+6 == 8 大家都懂的哈哈