none
控件重绘问题 RRS feed

  • 问题

  • 在formload事件中加入以下代码:
    System.Windows.Forms.Button myButton = new System.Windows.Forms.Button();
    myButton.BackColor = Color.Blue; //Lets change the color
    myButton.Size = new Size(100, 100);
    System.Drawing.Drawing2D.GraphicsPath myGraphicsPath = new System.Drawing.Drawing2D.GraphicsPath(); //The GraphicsPath class allows us to define custom paths
    myGraphicsPath.AddEllipse(5, 5, 90, 90); //A big circle
    myButton.Region = new Region(myGraphicsPath); //Associating the path made by us to the button's region
    this.Controls.Add(myButton);

    这样会得到一个圆形按钮,但他的边框有很多锯齿,如何消除呢?
    2009年5月6日 13:04

答案

  • 试下这个方法, 我处理Form.Paint事件,绘制一下背景,能够消除锯齿.

    Public Class Form1
        Dim myButton As Button
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            myButton = New System.Windows.Forms.Button()
            Me.DoubleBuffered = True
            myButton.BackColor = Color.Blue
            'Lets change the color
            myButton.Size = New Size(100, 100)
            Dim myGraphicsPath As New System.Drawing.Drawing2D.GraphicsPath()
            'The GraphicsPath class allows us to define custom paths
            myGraphicsPath.AddEllipse(5, 5, 90, 90)
            'A big circle
            myButton.Region = New Region(myGraphicsPath)
            'Associating the path made by us to the button's region
            Me.Controls.Add(myButton)
        End Sub
        Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
            e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
            e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            e.Graphics.FillEllipse(Brushes.Blue, New Rectangle(Me.myButton.Location.X, Me.myButton.Location.Y, Me.myButton.Width, Me.myButton.Height))
        End Sub
    End Class

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • 已标记为答案 ogra 2009年5月8日 6:21
    2009年5月8日 6:05
    版主

全部回复

  • 你好!
         如果你直接画可以这样:
            private void form1_Paint(object sender, PaintEventArgs e)
            {
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                e.Graphics.DrawEllipse(Pens.Red, 100, 100, 100, 100);
            }
         你这样指定区域的话我还没有想到办法啊!
    周雪峰
    2009年5月6日 14:49
    版主
  • 你好。你的画法我是知道的。
    其实源头是我需要做一个类似vb的shape的控件。
    我开始就是用你的方法画。然后让背景透明。
    我让背景透明的办法是这样的。
    新建一个用户控件,让它继承自UserControl
    重写相关的属性方法
     //背景透明
            protected override CreateParams CreateParams
            {
                get
                {
                    //用于继承类以在获取属性值时调用非托管代码
                    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
                    CreateParams cp = base.CreateParams;
                    cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
                    return (cp);
                }
            }
            protected override void OnPaintBackground(PaintEventArgs e)
            {
                //do nothing
            }

    使用上述的办法确实能够使控件透明,但却有一个问题。
    当用上述方法生成的透明控件堆在一起时,
    控件的Z-Order会变得很混乱。使用SendToBack和BringToFront会造成很多意料之外的效果。用SetChildIndex也一样。所以我就考虑,直接让控件的形状变成所需的形状(比如让控件变成圆,椭圆等),但我又发现,这样画出的控件边缘的锯齿无法消除。
    请问,在.netframwork2.0下(这个实在没办法,再高的版本实在太大,而且又不能有选择性的部署),我还有其他的解决方案吗?

    2009年5月7日 0:01
  • 你参考一下这个实现:
    http://www.codesoso.com/code/Jagged-Eliminate.aspx
    周雪峰
    2009年5月7日 0:49
    版主
  • 那个看的我头晕。还是没看懂。我想用GraphicsPath的SetClip的方法,减去锯齿点集合。但我还不知算法如何。

    2009年5月7日 8:30
  • 可是GraphicsPath没有SetClip方法啊!
    周雪峰
    2009年5月7日 9:04
    版主
  • 。。。。,搞错了,是graphics的
    http://msdn.microsoft.com/zh-cn/library/0z994t06.aspx

    2009年5月7日 9:08
  • 用这个重载:
    http://msdn.microsoft.com/zh-cn/library/661tzs47.aspx
    然后设置SmoothingMode属性看看!
    周雪峰
    2009年5月7日 9:12
    版主
  • 啊?什么意思啊,我比较笨,没看懂你的意思。
    我找到了一个widen方法,不知有没用
    http://msdn.microsoft.com/zh-cn/library/2215759c.aspx
    2009年5月7日 9:24
  • 试下这个方法, 我处理Form.Paint事件,绘制一下背景,能够消除锯齿.

    Public Class Form1
        Dim myButton As Button
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            myButton = New System.Windows.Forms.Button()
            Me.DoubleBuffered = True
            myButton.BackColor = Color.Blue
            'Lets change the color
            myButton.Size = New Size(100, 100)
            Dim myGraphicsPath As New System.Drawing.Drawing2D.GraphicsPath()
            'The GraphicsPath class allows us to define custom paths
            myGraphicsPath.AddEllipse(5, 5, 90, 90)
            'A big circle
            myButton.Region = New Region(myGraphicsPath)
            'Associating the path made by us to the button's region
            Me.Controls.Add(myButton)
        End Sub
        Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
            e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
            e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            e.Graphics.FillEllipse(Brushes.Blue, New Rectangle(Me.myButton.Location.X, Me.myButton.Location.Y, Me.myButton.Width, Me.myButton.Height))
        End Sub
    End Class

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • 已标记为答案 ogra 2009年5月8日 6:21
    2009年5月8日 6:05
    版主
  • 此法可行啊,谢谢Riquel_Dong
    2009年5月8日 6:22