2016-05-03 55 views
0

C#後 - .Net4.0,Visual Studio 2010中C#自定義控件 - 重繪改變成員對象的屬性

因爲某種原因,我使用一個單獨的類來存儲我的一些自定義的控件的屬性(屬性做繪製網格)。這導致了一些問題,因爲我希望在任何時候編輯這些值(無論是通過屬性窗口還是運行時)都可以調用「Invalidate()」來自動重繪控件。我能想到的最好的解決方案是在我的「GridProperties」類中實現INotifyPropertyChanged,每次調用相關的「set」訪問器時觸發PropertyChanged事件,然後從我的控件類訂閱PropertyChanged事件處理程序以調用「重繪「方法(它只是調用Invalidate())。

到目前爲止,這是我的代碼的縮短版本。

class MyControl : Control 
{ 
    [Browsable(true)] 
    public GridProperties Grid { get; set; } 

    public MyControl() 
    { 
     Grid = new GridValues(); 
     Grid.Columns = 4; 
     Grid.Rows = 4; 
     Grid.ShowGridLines = true; 

     Grid.PropertyChanged += Redraw; 
    } 

    private void Redraw (object sender, PropertyChangedEventArgs e) 
    { 
     Invalidate(); 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     //draw gridlines 
     //draw columns/ rows 
    } 
} 


class GridProperties : INotifyPropertyChanged 
{ 
    private int columns; 
    private int rows; 
    private bool showGridLines; 

    public int Columns 
    { 
     get { return columns; } 
     set 
     { 
      if (columns != value) 
      { 
       columns = value; 
       NotifyPropertyChanged("Columns"); 
      } 
     } 
    } 

    public int Rows... 
    //same kinda deal for rows & showGridLines 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(string info) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
    } 
} 

我期待什麼:重繪被調用值以任何方式改變任何時候Grid.Columns/Grid.Rows/Grid.ShowGridLines(希望通過屬性窗口太)。

會發生什麼:重繪不會被調用,除非我做這樣的事情,在一個全新的方法MyControl:

Grid.PropertyChanged += Redraw; 
Grid.ShowGridLines = false; 

這在運行時的工作,但是這違背了使用事件點經理,因爲我可以設置值,然後每次調用失效,並且它不會幫助通過屬性窗口進行的任何更改。

如果任何人都可以給我一個關於我做錯了什麼的問題或者是否有更好的方法,我會非常感激。誠實地說,我甚至不確定訂閱會員的活動經理是否是好的做法。

+0

嗯,也許你的網格屬性被替換?如果該屬性應該被允許完全重新創建,那麼在你的setter上,你必須鉤住PropertyChanged事件(同時解除以前的GridProperties實例),否則移除setter以避免問題(你可以使用c#6.0的屬性初始值設定項或私有setter對於以前的版本)。 – Gusman

+0

我猜你是對的;我做了你所推薦的東西,並且在Grid的setter中連接了PropertyChanged事件,現在它似乎完美地工作了。發現它很奇怪,因爲我沒有想到我明確替換了Grid(除了在MyControl的構造函數中初始化它),但是無論哪種方式,現在都很高興!謝謝。 – 9bjames

+0

很高興它的工作。設計人員很可能會替換您的GridProperties,您可以檢查.designer.cs文件,應該有分配。 – Gusman

回答

1

感謝古斯曼的解決方案。相反,從MyControl的構造函數中掛鉤到的PropertyChanged的,我只是迷上了它從電網的setter內,像這樣:

private GridProperties grid; 
[Browsale(true)] 
public GridProperties Grid 
{ 
    get 
    { 
     return grid; 
    } 
    set 
    { 
     if(grid! = null) 
      grid.PropertyChanged -= Redraw; 

     grid = value; 
     grid.PropertyChanged += Redraw; 
    } 
} 

我只能假設的東西是我的替換對象GridProperties某處。無論哪種方式,任何時候都可以訪問Grid的setter我只要解除/鉤住PropertyChanged事件管理器,現在無論是通過代碼還是從屬性窗口更改Grid的值,屏幕都會更新。