2016-07-25 10 views
0

良い日、私はVisual Studioの標準コントロールに基づいていくつかのカスタムコントロールを作成していますが、フラットスタイルアプリケーション私が通常作るものです。私はかなりの機能コントロールを既に行っているので、すべてはうまくいっています。VS2015カスタムコントロールでInvalidate()を使用するとコミュニティクラッシュが発生する

Visual Studioがクラッシュしたために作業が途切れてしまったため、私は調査して、少なくともその根本的な問題を発見しました。

境界線をオンまたはオフにするブール値(下の図を参照)を使用してデザインを使用して変更できる変数を初期化するときは、前記変数のSetイベント中にthis.Invalidate()コマンドを呼び出したいと思います。しかし、コード行を追加して[ソリューションのビルド]をクリックするか、[デザイン]ビューに移動すると、Visual Studioが完全にフリーズし、タスクマネージャでWindowsエラー報告プロセスが実行されています。

Visual Studioをプロジェクトに直接再起動するたびに、エラーが原因でVisual Studioがクラッシュし、開いていたファイルが読み込まれないというポップアップが表示されます。

これは私がDrawMode = DrawMode.OwnerDrawFixedを設定しても、私のカスタムコントロールと変数のいずれかで発生し、また、すべてのSetStyle()

EDIT調整し、注意してください:私が削除した場合

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

:Apologiez、コードサンプルを'this.Invalidate()'は 'set {}'から完全に動作します。

+0

あなたは[デザインタイム]を区別しなければならない(http://stackoverflow.com/q/ 1166226/1997232)、これは実行時と同じではありません。さらに助けが必要な場合は、関連するコードを投稿に追加することを検討してください。誰も[写真からのコード](http://meta.stackoverflow.com/q/303812/1997232)をコピーするつもりはない。 – Sinatr

+0

これは、変数をデザインやランタイムに制限するように見えるでしょうか?変数は、実行時および設計時に設定できる必要があります。私はコントロールに固有のテーマエンジンを実装しています。これは必要ではありませんが、プログラム全体をビルドして実行することに反対する「ライブ」アップデートを使用するとよいでしょう。ああ、私は写真を削除しました。 – Hurly

答えて

0

このプロパティのセッターは、無限再帰があります

[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

関連する問題