简体   繁体   中英

VS2015 Community Crashes when using Invalidate() in custom Control

Good day, I'm in the process of making a few custom controls based off of the standard controls in Visual Studio, but adding more functionality for Flat-style applications, which is what I normally make. All is going well with it as I have made quite a few functional controls already.

Upon having way too much work lost due to my Visual Studio crashing, I investigated and found the issue, well, the root of it at least.

Whenever I initialize a variable that can be modified using the design, say a Boolean that turns a border on or off (see pictures below), I would like to call the this.Invalidate() command during the Set event of said variable. But whenever I add the line of code and either click Build Solution or go into Design view, my Visual Studio freezes completely, and I find a Windows Error Reporting process running in Task Manager, this never returns an error which I could use.

Everytime I restart my Visual Studio straight into the project, a popup appears that tells me Visual Studio crashed due to an error and did not load any of the files I had open.

Please note, this happens on ANY of my custom controls and variables even if I set DrawMode = DrawMode.OwnerDrawFixed , and also adjusted all the SetStyle()

EDIT: Apologiez, Code samples:

[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);
}

If I remove 'this.Invalidate()' from the 'set{}' it works perfectly.

This property setter has endless recursion:

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

Change it to normal full property:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM