学海无涯

导航

GDI+经验

C#指定控件的绘图区域

摘要:怎么裁剪隐藏擦除某个控件的其中一部分呢,网上很多教程都是基于一张透明图片去生成区域,然后在这个区域绘制控件,其实不用图片也可以实现,我在这里找到了答案。通过这个方法,我们可以实现很多效果,比如绘制一个不规则的控件,包括圆角矩形三角形圆形等。

 

C#怎么裁剪/隐藏/擦除某个控件的其中一部分呢,网上很多教程都是基于一张透明图片去生成区域,然后在这个区域绘制控件,其实不用图片也可以实现,我在这里找到了答案。实现代码如下:

GraphicsPath controlPath = new System.Drawing.Drawing2D.GraphicsPath();
            // 绘制两个区域
            controlPath.AddRectangle(new System.Drawing.Rectangle(10, 10, 50, 50));
            controlPath.AddRectangle(new System.Drawing.Rectangle(50, 50, 100, 100));
            
            // 反选区域
            Region r = new Region(new Rectangle(Point.Empty, this.ClientSize));
            r.Exclude(controlPath);
            
            // 设置button1绘图区域
            button1.Region = r; // 如果不需要反选的话,把r换成controlPath也是可以的

  

下面是效果,实现了一个镂空的button,点击镂空的部分会穿透到下一层,而且两个镂空区域的交叉部分竟然是实心的,是不是感觉很神奇。

通过这个方法,我们可以实现很多效果,比如绘制一个不规则的控件,包括圆角矩形、三角形、圆形等。

 /// <summary>
        /// 初始化控件
        /// 预设绘图方式:双缓冲、支持透明背景色、自定义绘制
        /// </summary>
        public ThermometerControl()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.Selectable, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.UserPaint, true);

            InitializeComponent();
        }

 

C#自定义工业控件开发

 

解决WinForm自定义控件刷新时闪烁问题

最近遇到由于窗口内其它控件变动导致自定义地图控件闪烁的问题,体验特别不好,所以需要想办法解决这个问题。

自定义地图控件的逻辑是在控件触发OnPaint事件时,将地图内容绘制到控件Graphic上,曾经尝试在OnPaint中做处理,但是没有效果,后来才意识到闪烁的根本原因是控件做了清除操作,变白了再做绘制就会让人感觉到是在闪烁。

在网上找到了这篇文章,winform控件大小改变是防止背景重绘导致的闪烁,在自定义地图控件中重写OnPaintBackground方法后验证此问题得到解决

/// <summary>
/// OnPaintBackground 事件
/// </summary>
/// <param name="e"></param>
protected override void OnPaintBackground(PaintEventArgs e)
{
    // 重载基类的背景擦除函数,
    // 解决窗口刷新,放大,图像闪烁
    return;
}

  接下来需要考虑不做清除操作会带来什么问题,比如在图层设置成半透明时,如果不做清屏效果会不会叠加,不做清屏会不会有些不是本次刷新需要显示的内容还残留在地图上等,但是经过验证这些问题都不存在,因为地图的绘制机制会做一个背景填充的操作,效果目前一切正常。

c#自定义控件中OnPaint事件不触发更新

可能是因为控件没有被正确创建或初始化导致OnPaint事件不被触发。可以尝试在构造函数中调用SetStyle方法,将ControlStyles.UserPaint和ControlStyles.AllPaintingInWmPaint设置为true。此外,还可以尝试在处理OnPaint事件时添加Invalidate()方法以实现更新。

代码示例:

public class CustomControl : Control
{
    public CustomControl()
    {
        SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // 绘制控件的自定义内容
        base.OnPaint(e);
        Invalidate();
    }
}

c# 自定义控件 顶层 panel

C# 中自定义控件的实现方式有很多,其中一种方式是继承 Panel 控件并在其上添加自定义控件。如果您希望将自定义控件放置在 Panel 控件的顶层,可以使用 Panel 控件的 Controls 属性进行控制。

以下是实现方法的步骤:

  1. 创建一个自定义控件类,可以继承自 Control 或者其他合适的控件类。在自定义控件类中添加需要的控件和功能,为了方便本文以自定义控件类名为 MyCustomControl。

  2. 创建一个 Panel 控件,并添加 MyCustomControl 实例。

  3. 设置 MyCustomControl 控件的 Dock 属性为 Fill,使其充满整个 Panel 控件。

  4. 将 MyCustomControl 控件的 BringToFront() 方法调用,使其位于 Panel 控件的顶层。

下面是一个简单的示例代码:

public class MyCustomControl : Control
{
    public MyCustomControl()
    {
        // 在此添加自定义控件
    }
}

// 在窗体中使用 Panel 控件和 MyCustomControl 实例
Panel myPanel = new Panel();
MyCustomControl myCustomControl = new MyCustomControl();
myPanel.Controls.Add(myCustomControl);
myCustomControl.Dock = DockStyle.Fill;
myCustomControl.BringToFront();

  这样就可以在 Panel 控件的顶层添加自定义控件了。需要注意的是,如果在添加自定义控件之前已经添加了其他控件,那么需要使用 SendToBack() 方法将其放到底层,否则自定义控件将无法显示在顶层。

注意:

请勿直接从控件调用 OnPaint;请改为调用 Invalidate 方法(从 Control 继承)或调用 Invalidate 的其他方法。 Invalidate 方法又会调用 OnPaint。 重载 Invalidate 方法,并根据提供给 Invalidatee 的参数重绘其部分屏幕区域或整个屏幕区域

 自定义滑动条

 

在控件上绘图(Windows 窗体 .NET)

 

posted on 2024-01-10 21:57  宁静致远.  阅读(17)  评论(0编辑  收藏  举报