C# winfrom 设置控件透明背景色,比如TextBox

该代码段展示了如何在C#中创建一个支持透明背景的文本框控件,使用了WinAPI函数LoadLibrary加载msftedit.dll,设置控件风格为透明,并且定义了RICHEDIT50W类名以实现特定的文本编辑功能。同时,代码处理了焦点变化、键盘事件以及文本更改事件,提供了自定义的边框样式。
摘要由CSDN通过智能技术生成
 public partial class Text : TextBox
    {
        public Text()
        {
            this.BorderStyle = BorderStyle.FixedSingle;
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            InitializeComponent();
        }
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr LoadLibrary(string lpFileName);

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams prams = base.CreateParams;
                if (LoadLibrary("msftedit.dll") != IntPtr.Zero)
                {
                    prams.ExStyle |= 0x020; // transparent 
                    prams.ClassName = "RICHEDIT50W";// TRANSTEXTBOXW
                }
                return prams;
            }
        }  
    }
  public partial class TextBoxRua : Control
    {
        public TextBoxRua()
        {
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
            m_tbx = new Text();
            m_tbx.Multiline = true;
            m_tbx.BorderStyle = BorderStyle.None;
            this.BackColor = Color.Transparent;
            m_tbx.GotFocus += (s, e) => { m_bFocus = true; this.Invalidate(); };
            m_tbx.LostFocus += (s, e) => { m_bFocus = false; this.Invalidate(); };
            m_tbx.KeyDown += (s, e) => this.OnKeyDown(e);
            m_tbx.KeyPress += (s, e) => this.OnKeyPress(e);
            m_tbx.KeyUp += (s, e) => this.OnKeyUp(e);
            m_tbx.TextChanged += (s, e) => this.OnTextChanged(e);
            //m_tbx.BackColorChanged += (s, e) => m_tbx.BackColor = Color.White;
            this.Controls.Add(m_tbx);
        }

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr LoadLibrary(string lpFileName);

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams prams = base.CreateParams;
                if (LoadLibrary("msftedit.dll") != IntPtr.Zero)
                {
                    prams.ExStyle |= 0x020; // transparent 
                    prams.ClassName = "RICHEDIT50W";// TRANSTEXTBOXW
                }
                return prams;
            }
        }
        public override string Text
        {
            get { return m_tbx.Text; }
            set
            {
                if (m_tbx.Text == value) return;
                m_tbx.Text = value;
            }
        }

        public Text TextBox
        {
            get { return m_tbx; }
        }

        public override Color BackColor
        {
            get { return Color.Transparent; }
            set { }
        }

        public override Color ForeColor
        {
            get { return base.ForeColor; }
            set
            {
                if (base.ForeColor == value) return;
                base.ForeColor = value;
                m_tbx.ForeColor = value;
            }
        }

        private bool _ReadOnly;

        public bool ReadOnly
        {
            get { return m_tbx.ReadOnly; }
            set { m_tbx.ReadOnly = value; m_tbx.BackColor = Color.Transparent; }
        }

        private Text m_tbx;
        private bool m_bFocus;

        public event EventHandler TextChanged;

        protected virtual void OnTextChanged(EventArgs e)
        {
            if (this.TextChanged != null) this.TextChanged(this, e);
        }

        protected override void OnResize(EventArgs e)
        {
            m_tbx.Left = m_tbx.Top = 3;
            m_tbx.Width = this.Width - 6;
            m_tbx.Height = this.Height - 6;
            base.OnResize(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            using (SolidBrush sb = new SolidBrush(Color.Transparent))
            {
                g.FillPath(
                    sb,
                    GetRoundRectPath(new Rectangle(0, 0, this.Width - 1, this.Height - 1), 5)
                    );
            }
            using (LinearGradientBrush lgb = new LinearGradientBrush(
               new Point(0, 1), new Point(0, this.Height),
               Color.LightGray, Color.White))
            {
                g.DrawPath(
                    new Pen(lgb),
                    GetRoundRectPath(new Rectangle(0, 1, this.Width - 1, this.Height - 2), 5)
                    );
            }
            using (LinearGradientBrush lgb = new LinearGradientBrush(
               new Point(0, 0), new Point(0, this.Height - 1),
               m_bFocus ? Color.DodgerBlue : Color.Gray, Color.FromArgb(20, 0, 0, 0)))
            {
                g.DrawPath(new Pen(lgb), GetRoundRectPath(new Rectangle(0, 0, this.Width - 1, this.Height - 2), 5));
            }
            base.OnPaint(e);
        }

        /// <summary>
        /// 适合调整参数radius...
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="radius">radius 角度</param>
        /// <returns></returns>
        public GraphicsPath GetRoundRectPath(RectangleF rect, float radius)
        {
            return GetRoundRectPath(rect.X, rect.Y, rect.Width, rect.Height, radius);
        }

        public GraphicsPath GetRoundRectPath(float X, float Y, float width, float height, float radius)
        {
            GraphicsPath path = new GraphicsPath();
            path.AddLine(X + radius, Y, (X + width) - (radius * 2f), Y);
            path.AddArc((X + width) - (radius * 2f), Y, radius * 2f, radius * 2f, 270f, 90f);
            path.AddLine((float)(X + width), (float)(Y + radius), (float)(X + width), (float)((Y + height) - (radius * 2f)));
            path.AddArc((float)((X + width) - (radius * 2f)), (float)((Y + height) - (radius * 2f)), (float)(radius * 2f), (float)(radius * 2f), 0f, 90f);
            path.AddLine((float)((X + width) - (radius * 2f)), (float)(Y + height), (float)(X + radius), (float)(Y + height));
            path.AddArc(X, (Y + height) - (radius * 2f), radius * 2f, radius * 2f, 90f, 90f);
            path.AddLine(X, (Y + height) - (radius * 2f), X, Y + radius);
            path.AddArc(X, Y, radius * 2f, radius * 2f, 180f, 90f);
            path.CloseFigure();
            return path;
        }
    }

 

当您在C# WinForm应用中遇到控件属性刷新慢的问题时,这通常是由于系统处理图形界面元素的方式导致的性能瓶颈。以下是一些常见的原因及解决策略: ### 原因分析 1. **事件循环**:WinForms UI线程会不断检查事件队列,并在接收到事件时刷新相应的控件。频繁的UI更新可能会占用大量的CPU资源,特别是在复杂用户交互的情况下。 2. **长时间运行的任务**:如果应用程序中有长时间运行的任务(如数据加载、图像处理等),并且没有适当管理其执行环境(例如通过异步操作),则可能导致UI响应变慢。 3. **大量控件更新**:对大量控件进行快速更新同样会影响性能。特别是当每次更新都涉及到大量的样式改变或内容填充时,效率会明显降低。 4. **无效的缓存机制**:某些情况下,WinForms缓存了控件的更新状态,在不需要的情况下尝试更新已修改的状态,这也可能增加性能开销。 ### 解决策略 1. **异步处理**:对于耗时的操作,使用`async`和`await`关键字将任务异步化。避免在主线程上进行长运行操作,而是将其放入另一个线程池中执行。 2. **优化UI更新**:尽量减少在每个事件循环中更新控件的数量。只更新真正需要改变的部分,而不是整个界面。可以利用`Control.Invoke`或`Control.BeginInvoke`方法在后台线程上执行更新。 3. **缓存机制调整**:合理设置控件的缓存机制,避免不必要的重渲染。可以手动控制何时更新控件的布局和外观属性,以及何时释放旧的渲染信息。 4. **性能监控**:使用诸如`Visual Studio Performance Profiler`之类的工具来定位性能瓶颈。识别出哪些部分消耗了过多的时间或资源,针对性地进行优化。 5. **代码重构**:评估现有的代码结构是否高效。可能存在一些冗余的计算或未充分利用的缓存机制的情况,通过对代码进行重构来提高整体效率。 6. **使用更现代的框架**:考虑迁移到.NET Core或ASP.NET Core这样的现代框架,它们提供更先进的UI模型和支持更高效的并发处理技术。 --- ### 相关问题 1. **如何识别和定位UI性能瓶颈?** 2. **异步编程在C#中如何应用到WinForm项目中?** 3. **在WinForm中实现更流畅的UI动画效果需要关注哪些方面?** 请记住,解决此类问题通常需要综合考虑多个因素,包括代码设计、程序架构以及硬件限制。持续的优化过程可以帮助提升用户体验并改善系统的整体性能。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值