2014-10-08 223 views
1

我创建从具有以下属性的基础自定义控件继承了一些自定义控件:自定义属性

public Color BorderColor 
    { 
     get { return BorderColor; } 
     set 
     { 
      if (!FollowsScheme) 
       BorderColor = value; 
     } 
    } 

    public Color[] FillColors 
    { 
     get { return FillColors; } 
     set 
     { 
      if (!FollowsScheme) 
       FillColors = value; 
     } 
    } 

    public bool FollowsScheme { get; set; } 

我想使它所以如果用户设置FollowsScheme为假,才把他们可以编辑BorderColor和FillColors属性。如果FollowsScheme为真,那么他们不能编辑这两个属性。在该代码中,您可以看到我试图做的和想到的工作,但是当我构建解决方案并将控件添加到窗体时,Visual Studio崩溃。我应该怎么做?

让我更好地解释一下,如果FollowsScheme设置为true,OnPaint方法代码将绘制基于BorderColor和FillColors属性的控件,该属性基于填充了我设计的主题的颜色的静态类。如果FollowsScheme设置为false,则OnPaint方法将采用BorderColor和FillColors属性并计算一个新方案,并将这些颜色设置为列出的私有属性,然后这些将用于绘制控件。

回答

3

注意,当您添加控件到您的窗体,Visual Studio将运行渲染该控件所需的代码,以便它可以在设计器中显示。

您的代码会抛出StackOverflowException,随后导致Visual Studio崩溃。

引发此异常是因为您的属性setter是无限递归的。该解决方案是引入一个backng场举行这样的值:

private Color borderColor; 
public Color BorderColor 
{ 
    get { return this.borderColor; } 
    set 
    { 
     if (!FollowsScheme) 
      this.borderColor = value; 
    } 
} 
+0

Huhhh,我总是看到在源代码支持的属性的字段,我从来没有意识到这就是它是!谢谢! – Minato 2014-10-08 20:15:10

+0

@Minato所有好人。请注意,您需要为* both *属性引入一个后台字段。如果能够充分回答您的问题,请考虑将此答案标记为已接受的答案。 – 2014-10-08 20:21:05

+0

是的,我实际上正在等待,直到我被允许作出接受的答案,我失去了踪迹。再次感谢。 – Minato 2014-10-08 20:37:00

0

您设置的属性属性setter

public Color BorderColor 
{ 
    get { return BorderColor; } 
    set 
    { 
     if (!FollowsScheme) 
      BorderColor = value; // BOOM! 
    } 
} 

你需要使用一个支持成员变量为您的属性里面,通常是这样的:

private Color borderColor; 
public Color BorderColor 
{ 
    get { return borderColor; } 
    set 
    { 
     if (!FollowsScheme) 
      borderColor = value; 
    } 
}