【问题标题】:Unable to use the overridden BackColor property of a UserControl无法使用 UserControl 的被覆盖的 BackColor 属性
【发布时间】:2020-04-21 02:08:27
【问题描述】:

场景

我正在使用 UserControl 来创建自定义控件。

我正在尝试覆盖 UserControl 的 BackColor 属性,以便在 UserControl 的 BackColor 属性更改时,控件的 BackColor 不会更改并且值存储在名为 BackColor_Value 的变量中:

这里是它的代码:

Color BackColor_Value = Color.FromKnownColor(KnownColor.ActiveCaption);
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Bindable(true)]
//[AmbientValue(false)]
//[DefaultValue(typeof(Color), "ActiveCaption")]
public override Color BackColor
{
      get
      {
          return BackColor_Value;
      }
      set
      {
          BackColor_Value = value;
      }
 }

注意: BackColor 只是存储在一个变量中,而不是在任何地方使用。

编辑:我想要完成的是在设置 UserControl 的 BackColor 属性时更改所选控件的 BackColor,使 UserControl 的背景颜色保持不变。

问题

由于某种原因,控件的背景颜色会根据我指定的变量 BackColor_Value 进行更改。

  • 为什么即使在我覆盖了该属性之后,默认功能仍然存在?
  • 我应该使用什么属性来阻止这种情况发生?

完整代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;

namespace MaterialUI_Control
{
    public partial class MaterialPanel : UserControl
    {
        public MaterialPanel()
        {
            InitializeComponent();
        }

        Color BackColor_Value = Color.FromKnownColor(KnownColor.ActiveCaption);
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Bindable(true)]
        [AmbientValue(false)]
        [DefaultValue(typeof(Color), "ActiveCaption")]
        public override Color BackColor
        {
            get
            {
                return BackColor_Value;
            }
            set
            {
                BackColor_Value = value;
                this.Refresh();
            }
        }
    }
}

【问题讨论】:

  • 在属性 getter 中设置 return Color.FromKnownColor(KnownColor.ActiveCaption);。即,不要返回BackColor_Value
  • 否则,使用public new Color BackColor,在构造函数中设置base.BackColor = Color.FromKnownColor(KnownColor.ActiveCaption);,在属性设置器中删除this.Refresh();(因为你实际上并没有改变任何东西)。
  • BackColor 属性将被OnPaintBackground 方法用于呈现控件。如果要将BackColor 属性用于其他目的,则需要覆盖OnPaintBackground 以不依赖BackColor。或者您可以隐藏/隐藏属性public new Color BackColor { get; set; }。但总的来说,对我来说,这看起来像是一个 XY 问题。您要解决的读取问题是什么?

标签: c# winforms user-controls .net-3.5 gdi


【解决方案1】:

BackColor 属性将被OnPaintBackground 方法用于呈现控件。如果您想将BackColor 属性用于其他目的,您可以使用以下任一选项:

  • 覆盖 OnPaintBackground 并自己绘制背景(忽略 BackColor
  • 隐藏/隐藏BackColor 属性

您还需要考虑关于BackColor 属性的另一个事实,它是ambient property,这意味着如果您不明确设置它,它将遵循父控件的BackColor 属性的值。

示例 1 - 覆盖 OnPaintBackground 并自己绘制背景

您可以覆盖OnPaintBackground 方法并忽略BackColor 属性的值:

protected override void OnPaintBackground(PaintEventArgs e)
{
    var method = typeof(Control).GetMethod("PaintBackground",
        System.Reflection.BindingFlags.Instance |
        System.Reflection.BindingFlags.NonPublic,
        null,
        new Type[] { typeof(PaintEventArgs), typeof(Rectangle), typeof(Color) },
        null);

    //Paint with a default constant back color, here for example Color.Red
    method.Invoke(this, new object[] { e, ClientRectangle, Color.Red });
}

在这种情况下,更改背景颜色不会更改控件的呈现方式,但会更改未明确分配 BackColor 的子控件的 BackColor

示例 2 - 隐藏/隐藏 BackColor 属性

您可以隐藏/隐藏BackColor 属性:

public new Color BackColor { get; set; }

在这种情况下,改变背景颜色不会改变你的控件的渲染,它对子控件也没有影响,如果你想改变子控件的背景颜色,你需要在setter的setter中添加一些逻辑财产。

还要设置OnPaintBackground使用的颜色,在构造函数中可以设置base.BackColor = Color.Blue;什么的。

【讨论】:

  • 酷!没问题 :) 但是请确保它不是 XY 问题 ;)
  • 我正在做的事情是,在 UserControl 背景颜色更改时,我想使用已指定的背景颜色更改选择性控件。
  • 所以我想覆盖OnPaintBackground 作为解决方案更有意义。因为子控件将自动遵循您为父控件设置的BackColor,所以我们也为父控件使用了固定的背景颜色。
  • 您可以只在OnPaintBackground 中设置base.BackColor = [The predefined Color]; base.OnPaintBackground(e);。它具有相同的副作用(仅颜色名称会在 PropertyGrid 中更改),应该更正。但是,正如您所说,它看起来是一种解决问题的好奇方法。如果想要覆盖这个属性行为,只返回一个预定义的颜色,不管在设计器中设置了什么,你都可以删除该属性并在构造函数中设置base值。
猜你喜欢
  • 2018-03-02
  • 2015-01-08
  • 1970-01-01
  • 2014-08-18
  • 2016-12-18
  • 2013-01-19
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多