[C#]制作可以调整大小的自定义控件

当然,标题是为了降低大部分人的好奇心哭不过反正没人看。


这里说的并不是在VS的窗体设计器里调整控件大小,而是在程序运行起来后,在窗体中随意拖动调整控件大小。

如果用 鼠标的按键事件 来做,也可以,鼠标按下并拖动时计算鼠标位置然后改变控件大小即可。

但既然是自定义控件,就不应该那么麻烦。

只需要设置 Style 属性即可:

    public partial class TextBoxEx : TextBox
    {
        public TextBoxEx()
        {
            InitializeComponent();
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cm = base.CreateParams;
                cm.Style |= (int)0x00040000L;
                return cm;
            }
        }
    }


不过本文并不是什么教程之类,所以还是老实贴网址出来:

Style 的值:Window Styles

另外 CreateParams 还有一个可以“玩”的参数:Extended Window Styles

大概看下就能明白,VS 已经将它们大部分变为可视化的了,比如什么 BorderStyle,Visible之类的,但是了解一些底层的东西就可以在某些特殊的需求下做出自己想要的东西。


话说回来,样式效果并不尽人意,还需要其他参数来辅助调整


然后找到一个参数值:

WS_EX_STATICEDGE 0x00020000L

The window has a three-dimensional border style intended to be used for items that do not accept user input.

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cm = base.CreateParams;
                cm.Style |= 0x00040000;
                cm.ExStyle |= 0x00020000;
                return cm;
            }
        }


看起来比刚才好多了,不过这个 BorderSize 需要再调小一些,在这俩参数里找不到合适的了

于是想到重绘,但是网上看了看发现OnPaint无效

MSDN:重写 OnPaint 将禁止修改所有控件的外观。 那些由 Windows 完成其所有绘图的控件(例如 TextBox)从不调用它们的 OnPaint 方法,因此将永远不会使用自定义代码。

网上找的说要在 WndProc 里 Msg = 0xf 或 0x133 时重绘,0xf 还没找到,我觉得应该是加载完成的时候,有人知道说下可怜

WM_CTLCOLOREDIT

0x133

An edit control that is not read-only or disabled sends the WM_CTLCOLOREDIT message to its parent window when the control is about to be drawn. By responding to this message, the parent window can use the specified device context handle to set the text and background colors of the edit control.

然后折腾了半天,还是没能解决问题,貌似外面那个边框并不是 TextBox 所属范围

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg==0xf || m.Msg == 0x113)
            {
                using (Graphics g = this.CreateGraphics())
                {
                    Rectangle _border = new Rectangle(
                        -10, -10, this.Width + 20, this.Height + 20);
                    g.FillRectangle(Brushes.White, _border);//无法覆盖边框部分
                }
            }
        }

所以本文暂时以失败告终。


至于我要做什么,我想做桌面便签。。哭










版权声明:本文为shaoerbao原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。