2016-07-25 26 views
0

好日子,我正在根据Visual Studio中的标准控件制作一些自定义控件,但为Flat-style应用程序添加了更多功能是我通常做的。一切都很顺利,因为我已经做了很多功能控制。VS2015社区在自定义控件中使用Invalidate()时崩溃

由于我的Visual Studio崩溃导致失去了太多的工作,我调查并发现了问题,至少是它的根源。

每当我初始化一个可以使用设计修改的变量(比如说打开或关闭边框的布尔值)(参见下面的图片)时,我想在所述变量的Set事件期间调用this.Invalidate()命令。但是,无论何时添加代码行并单击Build Solution或进入设计视图,我的Visual Studio完全冻结,并且我发现Windows错误报告进程在任务管理器中运行,这永远不会返回我可以使用的错误。

每次我将Visual Studio直接重新启动到项目中时,会弹出一个窗口,告诉我Visual Studio由于错误而崩溃,并且未加载任何已打开的文件。

请注意,这发生在我的任何自定义控件和变量,即使我设置DrawMode = DrawMode.OwnerDrawFixed,并调整所有SetStyle()

编辑:Apologiez,代码示例:

[Category("Appearance")] 
public bool HasBorder 
{ 
    get 
    { 
     return HasBorder; 
    } 
    set 
    { 
     HasBorder = value; 
     this.Invalidate(); 
    } 
} 

public vComboBoxList() 
{ 
    Items = new List<object>(); 
    DataSource = new List<object>(); 
    SelectedItemColor = SystemColors.Highlight; 
    HoverItemColor = SystemColors.HotTrack; 
    BorderColor = SystemColors.ActiveBorder; 
    HasBorder = false; 
    ItemHeight = 16; 
    BorderThickness = 2; 
} 
protected override void OnCreateControl() 
{ 
    base.OnCreateControl(); 
} 
protected override void OnPaint(PaintEventArgs e) 
{ 
    Height = Items.Count * ItemHeight; 
    if (Items.Count > 0) 
    { 
     foreach (object Item in Items) 
     { 
      if (Items.IndexOf(Item) == ItemOver) 
       e.Graphics.FillRectangle(new SolidBrush(HoverItemColor), new Rectangle(0, Items.IndexOf(Item) * ItemHeight, Width, ItemHeight)); 
      else if (Items.IndexOf(Item) != ItemOver) 
       e.Graphics.FillRectangle(new SolidBrush(BackColor), new Rectangle(0, Items.IndexOf(Item) * ItemHeight, Width, ItemHeight)); 
      e.Graphics.DrawString(Items.IndexOf(Item).ToString(), Font, new SolidBrush(ForeColor), new Point(4, Items.IndexOf(Item) * ItemHeight)); 
     } 
    } 
    if(HasBorder && BorderThickness != 0) 
    { 
     Rectangle _Top = new Rectangle(0, 0, Width, BorderThickness); 
     Rectangle _Right = new Rectangle(Width, 0, -BorderThickness, Height); 
     Rectangle _Left = new Rectangle(0, 0, BorderThickness, Height); 
     Rectangle _Bottom = new Rectangle(0, Height, Width, -BorderThickness); 
     e.Graphics.FillRectangles(new SolidBrush(BorderColor), new Rectangle[] { _Top, _Right, _Left, _Bottom }); 
    } 
    base.OnPaint(e); 
} 

如果我删除'set.Invalidate()'来自'set {}',它完美的工作。

+0

您有什么区别[设计时间](http://stackoverflow.com/q/ 1166226/1997232),它与运行时不一样。如果您需要进一步的帮助,请考虑将相关代码添加到帖子中。没有人会复制[图片中的代码](http://meta.stackoverflow.com/q/303812/1997232)。 – Sinatr

+0

区分似乎将变量限制为设计或运行时?变量应该可以在运行时设置,也可以在设计时设置。我正在实现一个特定于我的控件的主题引擎。虽然这不是必需的,但如果将“实时”更新作为对照来构建和运行程序,那将是非常好的。哦,我删除了图片。 – Hurly

回答

0

此属性setter有无限递归:

[Category("Appearance")] 
public bool HasBorder 
{ 
    get 
    { 
     return HasBorder; 
    } 
    set 
    { 
     HasBorder = value; // will call setter again, which will call setter, which ... 
     this.Invalidate(); 
    } 
} 

将其更改为正常的全属性:

bool _hasBorder; 
public bool HasBorder 
{ 
    get { return _hasBorder; } 
    set 
    { 
     _hasBorder = value; 
     Invalidate(); 
    } 
} 
+0

一些非常简单的东西,但它的工作原理! :-D谢谢你的快速反应和耐心。老实说,这是我第一次制作自定义控件。那是我第一次需要这样做。 – Hurly

相关问题