The OnPaintBackground method is never invoked for control derived from Button

不打扰是莪最后的温柔 提交于 2019-11-28 10:43:50

问题


I've made a class GradientButton which suppose to be a Button which is filled with gradient background.

I draw gradient filling in the OnPaintBackground() method. Unfortunately it is never invoked, of course I added a GradientButton to a Form via toolbox:

  public class GradientButton : Button {

        public Color Color1 { get; set; }
        public Color Color2 { get; set; }

        public float Angle { get; set; }

        public GradientButton() {
            Color1 = Color.YellowGreen;
            Color2 = Color.LightGreen;
            Angle = 30;
        }



        protected override void OnPaintBackground(PaintEventArgs e) {
            base.OnPaintBackground(e);
            Debug.WriteLine("This never prints");
            using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,
                                                                       Color1,
                                                                       Color2,
                                                                       Angle)) {
                e.Graphics.FillRectangle(brush, this.ClientRectangle);
            }
        }
        protected override void OnResize(EventArgs e) {
            base.OnResize(e);
            Invalidate();
        }
    }

Question: How fill the button's background with the gradient? Why OnPaintBackground is not invoked? As far as I know it should be calledbefore OnPaint method.


回答1:


This is because the Button class has ControlStyles.Opaque flag set, which according to the documentation:

If true, the control is drawn opaque and the background is not painted.

You can turn it off in your class constructor

SetStyle(ControlStyles.Opaque, false);

and your OnPaintBackground override will be invoked.

However, it would not help a lot - there is a reason the flag to be set to true - the OnPaint draws both background and face of the button, so whatever you do in OnPaintBackground will not have any affect of the button appearance. Unfortunately there is no option to paint just the background, so you need to override the OnPaint and actually draw everything yourself.




回答2:


You need to set the style of the form in the constructor ...

this.SetStyle(ControlStyles.UserPaint, true);

to ensure the OnPaint method is overridden. There are many settings for the ControlStyle which you can combine




回答3:


I would do this instead.

Firstly, change your constructor to this:

    public GradientButton()
   {
        Color1 = Color.YellowGreen;
        Color2 = Color.LightGreen;
        Angle = 30;
        Paint += new PaintEventHandler(GradientButton_Paint);
    }

And then add the below procedure:

    private void GradientButton_Paint(object sender,PaintEventArgs e)
    {
        Debug.WriteLine("This never prints");
        using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,Color1,Color2,Angle))
        {
            e.Graphics.FillRectangle(brush, this.ClientRectangle);
        }
    }

I'm not entirely sure why your code doesn't work, but the way I've described always works for me. Hope that's good enough.



来源:https://stackoverflow.com/questions/36793877/the-onpaintbackground-method-is-never-invoked-for-control-derived-from-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!