上边两幅图片中显示的异常有谁遇到过。别把后边一幅中的异常当做简单的空引用异常。空引用异常时最值得怀疑的,.net下边有很多与空引用一点关系都没有的东西都会抛出空引用。我在测试自己编写的一个ContextContainer时遇到的,代码贴到后边。ListCtrl一个UserControl,里边放了一个ListBoxEva(这是自己扩展出的,里边能放图片、Checkbox、radiobutton)。如果把ListBoxEva的Dock属性设置为Fill,就会出现问题。放ListBox一样会出现问题,只要设置dock属性为Fill。当New一个ListCtrl后,有一个默认大小,但是如果将它传给ContextContainer的构造函数,在构造函数里,它的大小就会变成2X2,没有任何编码去修改它,它就这么莫名其妙的变了。不管在外边把这个ListCtrl的Size设置为多少,都会变。
当尝试从弹出的提示中展开、查看各个属性值时,就会发生上边的异常。正常运行不会产生任何异常,不过运行过后弹出的大小只是一个黑点。即使不将ListBox属性设置为Fill,仍然有这个问题。只是弹出的不是一个黑点而已。不管怎样,执行完ContextContainer的构造函数中的下面一句后this.Size并没改成_dropDownContent.Size。
this.Size = _dropDownContent.Size;

解决方案 »

  1.   

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Drawing.Design;
    using System.ComponentModel;
    using System.Windows.Forms.VisualStyles;
    using System.Drawing.Drawing2D;namespace TR0217.ControlEx
    {
        public enum ContextMode
        {
            /// <summary>
            /// dropDownContent closed after singl click on it's child control
            /// </summary>
            SingleSelect,
            /// <summary>
            /// dropDownContent closed after lost focus
            /// </summary>
            MultiSelect,
            /// <summary>
            /// dropDownContent closed as soon as mouse moved out of the dropdown parent
            /// </summary>
            ToolTip
        }
        [ToolboxItem(false)]
        public class ContextContainer : ToolStripDropDown
        {
            private Control _dropDownContent;
            private ToolStripControlHost _dropDownAssistant;
            private ContextMode _contextMode;
            private Rectangle _activeRect;
            private bool _focusOnOpen;
            private bool _resizable = false;        public bool Resizable
            {
                get { return _resizable; }
                set { _resizable = value; }
            }
          
            public Control DropDownContent
            {
                get { return _dropDownContent; }
            }        public bool FocusOnOpen
            {
                get { return _focusOnOpen; }
                set { _focusOnOpen = value; }
            }        public ContextMode ContextMode
            {
                get 
                { 
                    return _contextMode; 
                }
                set 
                { 
                    _contextMode = value;
                }
            }        public ContextContainer(Control dropDownContent)
            {
                if (dropDownContent == null)
                {
                    throw new ArgumentNullException("dropdowncontent shoul not be null!");
                }            _dropDownContent = dropDownContent;
                this._activeRect = Rectangle.Empty;
                _dropDownAssistant = new ToolStripControlHost(dropDownContent);
                _contextMode = ContextMode.MultiSelect;
                this.Padding = this.Margin = _dropDownAssistant.Padding = _dropDownAssistant.Margin = Padding.Empty;
                this.Items.Add(_dropDownAssistant);
                this.AutoClose = true;
                //this.ResizeRedraw = true;
                this.MinimumSize = dropDownContent.Size;
                dropDownContent.MinimumSize = dropDownContent.Size;
                //this.MaximumSize = dropDownContent.Size;
                //dropDownContent.MaximumSize = dropDownContent.Size;
                this.Size = _dropDownContent.Size;
                _dropDownContent.Disposed += delegate(object sender, EventArgs e)
                {
                    _dropDownContent = null;
                    Dispose(true);
                };
                _dropDownContent.Paint += new PaintEventHandler(_dropDownContent_Paint);
                foreach (Control ctrl in _dropDownContent.Controls)
                {
                    ctrl.MouseClick += new MouseEventHandler(ctrl_MouseClick);
                }
            }        void _dropDownContent_Paint(object sender, PaintEventArgs e)
            {
                if(_resizable)
                    PaintSizeGrip(e);
                //if (_resizable)
                //{
                //    //drow a grip at correct plase
                //    if (_resizeRight)
                //    {
                //        if (_resizeBottom)
                //            Console.WriteLine("");//right-bottom
                //        else
                //            Console.WriteLine("");//right-top
                //    }
                //    else
                //    {
                //        if (_resizeBottom)
                //            Console.WriteLine("");//left-bottom
                //        else
                //            Console.WriteLine("");//left-top 
                //    }
                //}
            }        void ctrl_MouseClick(object sender, MouseEventArgs e)
            {
                if (_contextMode == ContextMode.SingleSelect)
                {
                    if(e.Button == MouseButtons.Left)
                        this.Hide();
                }
            }
            private void ShowContent()
            {
                if (_activeRect != Rectangle.Empty)
                {
                    Point location = new Point(_activeRect.Left, _activeRect.Bottom);
                    Rectangle screenRect = (Screen.FromRectangle(_activeRect)).WorkingArea;
                    _resizeRight = true;
                    _resizeBottom = true;
                    if (location.X + Size.Width > (screenRect.Left + screenRect.Width))
                    {
                        location.X = (screenRect.Left + screenRect.Width) - Size.Width;
                        _resizeRight = false;
                    }                if (location.Y + Size.Height > (screenRect.Top + screenRect.Height))
                    {
                        location.Y -= Size.Height + _activeRect.Height;
                        _resizeBottom = false;
                    }
                    Show(location, ToolStripDropDownDirection.BelowRight);
                }
            }        /// <summary>
            /// show the dropdown content as the control's context
            /// </summary>
            /// <param name="control"></param>
            public void Show(Control control)
            {
                if(control == null)
                    throw new ArgumentNullException("control shoul not be null!");
                _activeRect = control.RectangleToScreen(control.ClientRectangle);
                ShowContent();
            }        /// <summary>
            /// show the drop content as if a control occupy the rect area
            /// usually serve as screen tip
            /// </summary>
            /// <param name="rect">active rect, in screen coordiante</param>
            public void Show(Rectangle rect)
            {
                _activeRect = rect;
                ShowContent();
            }        protected override void OnOpening(System.ComponentModel.CancelEventArgs e)
            {
                if (_dropDownContent.IsDisposed || _dropDownContent.Disposing)
                {
                    e.Cancel = true;
                    return;
                }
                base.OnOpening(e);
            }        protected override void OnOpened(EventArgs e)
            {
                base.OnOpened(e);
                if (_focusOnOpen)
                {
                    _dropDownContent.Focus();
                }
                if (_contextMode == ContextMode.ToolTip)
                {
                    if (hHook == 0)
                    {
                        MouseHookProcedure = new HookProc(MouseHookProc);
                        hHook = SetWindowsHookEx(WH_MOUSE, MouseHookProcedure,
                            GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
                    }
                }
            }        protected override void OnClosed(ToolStripDropDownClosedEventArgs e)
            {
                if (hHook != 0)
                {
                    UnhookWindowsHookEx(hHook);
                    hHook = 0;
                }
                base.OnClosed(e);
            }        protected override void OnSizeChanged(EventArgs e)
            {
                if (_resizable)
                {
                    _dropDownContent.MinimumSize = this.Size;
                    //_dropDownContent.MaximumSize = this.Size;
                    _dropDownContent.Size = this.Size;
                }
                base.OnSizeChanged(e);
            }
            protected override void WndProc(ref Message m)
            {
                if (Resizing(ref m))
                {
                    return;
                }
                base.WndProc(ref m);
            }
      

  2.   


            public bool ProcessResizing(ref Message m)
            {
                if (m.Msg == 0x0084)
                {
                    m.Result = (IntPtr)(-1);
                    return true;
                }
                return false;
            }
            private bool _resizeRight = false;
            private bool _resizeBottom = false;
            private Rectangle rectGrip;
            private Rectangle rectHorizontal;
            private Rectangle rectVertical;
            private Rectangle rectThis;        private bool Resizing(ref Message m)
            {
                if (m.Msg == 0x0084)
                {
                    if (_resizable)
                    {
                        Point pt;
                        GetCursorPos(out pt);
                        rectThis = _dropDownContent.RectangleToScreen(_dropDownContent.ClientRectangle);
                        if (_resizeRight)
                        {
                            rectVertical = new Rectangle(rectThis.Right - 3, rectThis.Top + 3, 6, this.Height - 6);
                            if (_resizeBottom)//right-bottom
                            {
                                rectGrip = new Rectangle(rectThis.Right - 3, rectThis.Bottom - 3, 6, 6);
                                rectHorizontal = new Rectangle(rectThis.Left + 3, rectThis.Bottom - 3, this.Width - 6, 6);                            if (rectGrip.Contains(pt))
                                    m.Result = (IntPtr)(17);//right bottom
                                else if (rectHorizontal.Contains(pt))
                                    m.Result = (IntPtr)(15);//bottom
                                else if (rectVertical.Contains(pt))
                                    m.Result = (IntPtr)(11);//right
                            }
                            else//right-top
                            {
                                rectGrip = new Rectangle(rectThis.Right - 3, rectThis.Top - 3, 6, 6);
                                rectHorizontal = new Rectangle(rectThis.Left + 3, rectThis.Top - 3, this.Width - 6, 6);                            if (rectGrip.Contains(pt))
                                    m.Result = (IntPtr)(14);//right top
                                else if (rectHorizontal.Contains(pt))
                                    m.Result = (IntPtr)(12);//top
                                else if (rectVertical.Contains(pt))
                                    m.Result = (IntPtr)(11);//right
                            }
                        }
                        else
                        {
                            rectVertical = new Rectangle(rectThis.Left - 3, rectThis.Top + 3, 6, this.Height - 6);
                            if (_resizeBottom)//left-bottom
                            {
                                rectGrip = new Rectangle(rectThis.Left - 3, rectThis.Bottom - 3, 6, 6);
                                rectHorizontal = new Rectangle(rectThis.Left + 3, rectThis.Bottom - 3, this.Width - 6, 6);
                                if (rectGrip.Contains(pt))
                                    m.Result = (IntPtr)(16);//left bottom
                                else if (rectHorizontal.Contains(pt))
                                    m.Result = (IntPtr)(15);//bottom
                                else if (rectVertical.Contains(pt))
                                    m.Result = (IntPtr)(10);//left
                            }
                            else//left-top
                            {
                                rectGrip = new Rectangle(rectThis.Left - 3, rectThis.Top - 3, 6, 6);
                                rectHorizontal = new Rectangle(rectThis.Left + 3, rectThis.Top - 3, this.Width - 6, 6);
                                if (rectGrip.Contains(pt))
                                    m.Result = (IntPtr)(13);//left top
                                else if (rectHorizontal.Contains(pt))
                                    m.Result = (IntPtr)(12);//top
                                else if (rectVertical.Contains(pt))
                                    m.Result = (IntPtr)(10);//left
                            }
                        }
                        return true;
                    }//end of "if (_resizable)"
                }
                return false;
            }        private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
            private int hHook = 0;
            private const int WH_MOUSE = 14;
            private HookProc MouseHookProcedure;        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern bool UnhookWindowsHookEx(int idHook);        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern int GetCurrentThreadId();        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern IntPtr GetModuleHandle(string name);        [DllImport("User32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern void GetCursorPos(out Point pt);
            private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
            {
                Point pt;
                GetCursorPos(out pt);
                if (_contextMode == ContextMode.ToolTip)
                {
                    if (!_activeRect.Contains(pt))
                    {
                        this.Hide();
                    }
                }
                return CallNextHookEx(hHook, nCode, wParam, lParam);
            }        private VisualStyleRenderer sizeGripRenderer;
            public void PaintSizeGrip(PaintEventArgs e)
            {
                if (e == null || e.Graphics == null || !_resizable)
                {
                    return;
                }
                GraphicsState gs = null;
                Size clientSize = _dropDownContent.ClientSize;
                using (Bitmap gripImage = new Bitmap(0x10, 0x10))
                {
                    using (Graphics g = Graphics.FromImage(gripImage))
                    {
                        if (Application.RenderWithVisualStyles)
                        {
                            if (this.sizeGripRenderer == null)
                            {
                                this.sizeGripRenderer = new VisualStyleRenderer(VisualStyleElement.Status.Gripper.Normal);
                            }
                            this.sizeGripRenderer.DrawBackground(g, new Rectangle(0, 0, 0x10, 0x10));
                        }
                        else
                        {
                            ControlPaint.DrawSizeGrip(g, _dropDownContent.BackColor, 0, 0, 0x10, 0x10);
                        }
                    }
                    gs = e.Graphics.Save();
                    e.Graphics.ResetTransform();
                    if (!_resizeBottom)
                    {
                        if (!_resizeRight)
                        {
                            e.Graphics.RotateTransform(180);
                            e.Graphics.TranslateTransform(-clientSize.Width, -clientSize.Height);
                        }
                        else
                        {
                            e.Graphics.ScaleTransform(1, -1);
                            e.Graphics.TranslateTransform(0, -clientSize.Height);
                        }
                    }
                    else if (!_resizeRight)
                    {
                        e.Graphics.ScaleTransform(-1, 1);
                        e.Graphics.TranslateTransform(-clientSize.Width, 0);
                    }
                    e.Graphics.DrawImage(gripImage, clientSize.Width - 0x10, clientSize.Height - 0x10 + 1, 0x10, 0x10);
                    e.Graphics.Restore(gs);
                }
            }
        }//end of class
    }//end of namespace
      

  3.   

    这是图片地址,上边是ContextContainer的全部代码。有兴趣的可以帮忙看看。
    http://topic.csdn.net/u/20100924/15/69b43bf7-2ab8-4ca2-ad4b-a064bd282e9d.html?seed=736174406&r=68619784#r_68619784
      

  4.   

    图片地址
    http://tr0217.blog.163.com/album/#m=2&aid=124645305&pid=6420130310