winforms 使用容器更改borderColor的UserControl

1sbrub3j  于 2023-06-24  发布在  其他
关注(0)|答案(1)|浏览(110)

我想让“巴拉兹·提汉伊”在这里做同样的事情:https://stackoverflow.com/a/9772020/8458887但使用TableLayoutPanel。我测试了他的代码一个工作。但当我改变了TableLayoutPanel的TextBox不工作。
图片:第一个是“Balazs Tihanyi”TextBox,第二个是我的TableLayoutPanel

图2:这是添加TextBox时TableLayoutPanel的外观

更改后的代码:

public class BorderedPanel : UserControl
    {
        TableLayoutPanel tableLayoutPanel;

        public BorderedPanel()
        {
            tableLayoutPanel = new TableLayoutPanel()
            {
                BackColor = SystemColors.Window,
                //AutoSize = true,
                //CellBorderStyle = TableLayoutPanelCellBorderStyle.None,   //Single
                BorderStyle = BorderStyle.None,   //FixedSingle
                ColumnCount = 1,
                RowCount = 1,
                Location = new Point(-1, -1),
                //Dock = DockStyle.Fill,
                Anchor = AnchorStyles.Top | AnchorStyles.Bottom |
                         AnchorStyles.Left | AnchorStyles.Right
            };
            Control container = new ContainerControl()
            {
                Dock = DockStyle.Fill,
                Padding = new Padding(-1)
            };
            container.Controls.Add(tableLayoutPanel);
            //Controls.Add(tableLayoutPanel);

            DefaultBorderColor = SystemColors.ControlDark;
            FocusedBorderColor = Color.Red;
            BackColor = DefaultBorderColor;
            Padding = new Padding(1);
            Size = tableLayoutPanel.Size;
        }

        public Color DefaultBorderColor { get; set; }
        public Color FocusedBorderColor { get; set; }

        //public override string Text
        //{
        //    get { return textBox.Text; }
        //    set { textBox.Text = value; }
        //}

        protected override void OnEnter(EventArgs e)
        {
            BackColor = FocusedBorderColor;
            base.OnEnter(e);
        }

        protected override void OnLeave(EventArgs e)
        {
            BackColor = DefaultBorderColor;
            base.OnLeave(e);
        }

        //protected override void SetBoundsCore(int x, int y,
        //    int width, int height, BoundsSpecified specified)
        //{
        //    base.SetBoundsCore(x, y, width, height, specified);
        //}
    }

如何使用代码:

public Form1()
    {
        InitializeComponent();
        BorderedPanel borderedPanel = new BorderedPanel();
        borderedPanel.Location = new Point(73, 150);   //73, 150   //12, 10
        borderedPanel.Size = new Size(319, 25);
        Controls.Add(borderedPanel);
        //borderedPanel.Controls.Add(txtPath);
f0ofjuux

f0ofjuux1#

作为在面板的非工作区添加自定义边框的选项,您可以处理以下本机消息:

在下面的屏幕截图中,您可以看到一个带有BorderColorBorderWidth自定义属性的面板,其中的实现工作在从右到左模式和自动滚动模式下:

你可以克隆或下载代码:

我已经在Panel border size and border color – Customize nonclient area文章中解释了更多关于处理消息的细节,但在这里你也可以看到代码:

    • 面板**
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using static PanelBorderExample.Win32Helpers;
namespace PanelBorderExample
{
    public class PanelEx : Panel
    {
        public PanelEx()
        {
            BorderStyle = BorderStyle.FixedSingle;
        }
        private Color borderColor = Color.Blue;
        [DefaultValue(typeof(Color), "Blue")]
        public Color BorderColor
        {
            get { return borderColor; }
            set
            {
                if (borderColor != value)
                {
                    borderColor = value;
                    Redraw();
                }
            }
        }
        private int borderWidth = 16;
        [DefaultValue(16)]
        public int BorderWidth
        {
            get { return borderWidth; }
            set
            {
                if (value == 0)
                    throw new ArgumentException("The value should be greater than 0");
                if (borderWidth != value)
                {
                    borderWidth = value;
                    RecalculateClientSize();
                }
            }
        }

        protected override void WndProc(ref Message m)
        {
            if (BorderStyle != BorderStyle.FixedSingle)
            {
                base.WndProc(ref m);
                return;
            }
            if (m.Msg == WM_NCPAINT)
            {
                base.WndProc(ref m);
                WmNCPaint(ref m);
            }
            else if (m.Msg == WM_NCCALCSIZE)
            {
                base.WndProc(ref m);
                WmNCCalcSize(ref m);
            }
            else if (m.Msg == WM_NCHITTEST)
            {
                base.WndProc(ref m);
                WmNCHitTest(ref m);
            }
            else
                base.WndProc(ref m);

        }
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            Redraw();
        }
        private void Redraw()
        {
            RedrawWindow(Handle, IntPtr.Zero, IntPtr.Zero,
               RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
        }
        private void RecalculateClientSize()
        {
            SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0,
                SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOZOORDER);
        }
        private void WmNCCalcSize(ref Message m)
        {
            if (BorderStyle != BorderStyle.FixedSingle)
                return;

            if (m.WParam != IntPtr.Zero)
            {
                var nccsp = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALCSIZE_PARAMS));
                nccsp.rgrc[0].top += borderWidth - 1;
                nccsp.rgrc[0].bottom -= borderWidth - 1;
                nccsp.rgrc[0].left += borderWidth - 1;
                nccsp.rgrc[0].right -= borderWidth - 1;
                Marshal.StructureToPtr(nccsp, m.LParam, true);
                InvalidateRect(this.Handle, nccsp.rgrc[0], true);
                m.Result = IntPtr.Zero;
            }
            else
            {
                var clnRect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
                clnRect.top += borderWidth - 1;
                clnRect.bottom -= borderWidth - 1;
                clnRect.left += borderWidth - 1;
                clnRect.right -= borderWidth - 1;
                Marshal.StructureToPtr(clnRect, m.LParam, true);
                m.Result = IntPtr.Zero;
            }
        }
        private void WmNCPaint(ref Message m)
        {
            var dc = GetWindowDC(Handle);
            using (var g = Graphics.FromHdc(dc))
            {
                using (var p = new Pen(BorderColor, borderWidth) { Alignment = PenAlignment.Inset })
                {
                    if (VScroll && HScroll)
                    {
                        Rectangle bottomCornerRectangle = new Rectangle(
                            Width - SystemInformation.VerticalScrollBarWidth - borderWidth,
                            Height - SystemInformation.HorizontalScrollBarHeight - borderWidth,
                            SystemInformation.VerticalScrollBarWidth,
                            SystemInformation.HorizontalScrollBarHeight);
                        if (RightToLeft == RightToLeft.Yes)
                        {
                            bottomCornerRectangle.X = Width - bottomCornerRectangle.Right;
                        }
                        g.FillRectangle(SystemBrushes.Control, bottomCornerRectangle);
                    }
                    var adjustment = borderWidth == 1 ? 1 : 0;
                    g.DrawRectangle(p, 0, 0, Width - adjustment, Height - adjustment);
                }
            }
            ReleaseDC(Handle, dc);
            m.Result = IntPtr.Zero;
        }
        private void WmNCHitTest(ref Message m)
        {
            var pt = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
            var rect = Parent.RectangleToScreen(Bounds);
            if (((pt.X >= rect.Left && pt.X <= rect.Left + borderWidth) ||
                (pt.X >= rect.Right - borderWidth && pt.X <= rect.Right)) ||
                ((pt.Y >= rect.Top && pt.Y <= rect.Top + borderWidth) ||
                (pt.Y >= rect.Bottom - borderWidth && pt.Y <= rect.Bottom)))
                m.Result = (IntPtr)HTBORDER;
        }
    }
}
    • Win32Helpers**
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace PanelBorderExample
{
    public static class Win32Helpers
    {
        public const int WM_NCPAINT = 0x85;
        public const int RDW_INVALIDATE = 0x0001,
            RDW_ERASE = 0x0004,
            RDW_ALLCHILDREN = 0x0080,
            RDW_ERASENOW = 0x0200,
            RDW_UPDATENOW = 0x0100,
            RDW_FRAME = 0x0400;
        public const int WM_NCCALCSIZE = 0x0083;
        public const int SWP_FRAMECHANGED = 0x0020,
            SWP_NOMOVE = 0x0002,
            SWP_NOSIZE = 0x0001,
            SWP_NOZOORDER = 0x0004;

        public const int WM_NCHITTEST = 0x0084;
        public const int HTBORDER = 18;
        public const int HTHSCROLL = 6;
        public const int HTVSCROLL = 7;
        public const int HTCLIENT = 1;

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left, top, right, bottom;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct NCCALCSIZE_PARAMS
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            public RECT[] rgrc;
            public WINDOWPOS lppos;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct WINDOWPOS
        {
            public IntPtr hwnd;
            public IntPtr hwndInsertAfter;
            public int x;
            public int y;
            public int cx;
            public int cy;
            public uint flags;
        }
        public const int NM_FIRST = 0;
        public const int NM_CLICK = NM_FIRST - 2;
        public const int WM_REFLECT = 0x2000;
        public const int WM_NOFITY = 0x004e;
        public const int WM_CTLCOLORSCROLLBAR = 0x0137;
        [StructLayout(LayoutKind.Sequential)]
        public struct NMHDR
        {
            public IntPtr hwndFrom;
            public IntPtr idFrom;
            public int code;
        }
        [DllImport("user32.dll")]
        public static extern bool InvalidateRect(IntPtr hWnd, RECT lpRect, bool bErase);
        [DllImport("user32.dll")]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
        [DllImport("user32")]
        public static extern IntPtr GetWindowDC(IntPtr hwnd);
        [DllImport("user32.dll")]
        public static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprc, IntPtr hrgn, int flags);
        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        public static extern IntPtr SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);
    }
}

相关问题