NumericUpDown backcolor not working as expected

后端 未结 3 1777
我在风中等你
我在风中等你 2021-01-23 02:53

I recently had the need to write a version of the Windows NumericUpDown control which could highlight whether a value was mandatory. It needed to do this by changing the back co

相关标签:
3条回答
  • 2021-01-23 03:46

    Interesting question, it demonstrates how overriding virtual members can have unexpected side-effects. The core problem is your BackColor property getter, it always returns the _backColor property value, even if you forced it to a different value with IsMandatory. That property getter is also used by Winforms when it needs to draw the control background. So you'll return Blue which explains why you see blue in your screenshot.

    But oddly it still works for the text portion of the control. That's because NumericUpdown is made up of multiple controls. You've got a ContainerControl that sets the outer bounds and is the base class, you are overriding its BackColor property. But inside of it are two other controls, a TextBox that displays the text and a Control that displays the up/down buttons. Your BackColor property override does not override their BackColor properties. So the textbox portion will draw with the color you assigned to Base.BackColor

    To fix this, you are going to have to stop fibbing about the BackColor. With the extra constraint that you need to make sure that this still works at design time so that the actual BackColor gets serialized and not the MandatoryColor:

    [DefaultValue(typeof(Color), "Window"), Description("Overridden property")]
    override public Color BackColor {
        get {
            return base.BackColor;
        }
        set {
            _backColor = value;
            MyResetColors();
        }
    }
    
    private void MyResetColors() {
        base.BackColor = this.IsMandatory && !DesignMode ? this.MandatoryBackColor : _backColor;
    }
    
    0 讨论(0)
  • 2021-01-23 03:56

    The above method did not work out for me. My workaround was:

        private void smartRefresh()
        {
            if (oldBackColor != BackColor) {
                oldBackColor = BackColor;
                Hide();
                Application.DoEvents();
                Show();
                Application.DoEvents();
            }
        }
    

    With a private member oldBackColor.

    Now it always shows correctly but does not flicker.

    Addendum: I think some part of the Control doesn't get painted at all (I consider it a bug) as the "mispainted" bos around it is not uniformly colored an somtimes traces of the window that was there before can be seen.

    0 讨论(0)
  • 2021-01-23 03:57

    Windows does not properly/completely repaint the NumericUpDown control when it is disabled.

    See this post: NumericUpDown background colour change for disabled element

    Enabling / disabling the control after it is displayed is a work-around.

    0 讨论(0)
提交回复
热议问题