2012-08-30 111 views
13

我在嘗試我的第一個Windows窗體項目,之前完全基於Web並遇到了一些問題。我想將一個對象列表綁定到一個TabControl,並創建這個Tabs,然後通過每個選項卡的click事件訪問一個databound值。將數據綁定到Windows窗體TabControl

我想要結合的對象是

public class TreeNodeItem 
{ 
    private NTree<string> node; 

    public TreeNodeItem(NTree<string> node) 
    { 
     this.node = node; 
    } 

    public string Value 
    { 
     get { return this.node.data; } 
    } 
} 

的NTree節點表示一個對象的節點,在樹結構模型的數據。我想爲列表中的每個對象創建一個選項卡,將Value屬性綁定到Tab Text屬性。其他帖子提到綁定到控件的ItemsSource屬性,但Visual Studio沒有給我這個屬性。

任何幫助將不勝感激。

乾杯

斯圖爾特

+2

每一次我遇到這種情況,我會建立一個自定義控件(在我5年的開發工作中沒有看到過),或者找到另一種表示數據的方式。防爆。 treeList控件 – Marty

+0

這是世界上最簡單的事情......如果你使用'WPF'而不是'winforms'。如果你沒有歸屬於winforms,我建議使用WPF。我經常使用我的視圖模型來完成與標籤和標籤頁內容的數據綁定。如果wpf是一個選項,我可以提供一個例子。 –

+0

@NathanA我知道,我希望我使用的是WPF,因爲如果我是這麼簡單,但是我堅持使用WinForms – Rachel

回答

2

好吧,我不知道的是,結合是必須的。雖然我從來沒有在Windows窗體應用程序中看到過這樣的事情,但我決定創建一個類來爲我們做這件事。

它使用ObservableCollection<T>來跟蹤對象/屬性是否已在其列表中更改。

public class ObservableList<T> : ObservableCollection<T> 
    { 
     public ObservableList() : base() 
     { 
      CollectionChanged += new NotifyCollectionChangedEventHandler(nObservableCollection_CollectionChanged); 
     } 

     public event PropertyChangedEventHandler OnPropertyChanged; 

     void nObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
     { 
      if (OnPropertyChanged != null) 
      { 
       OnPropertyChanged(new object[] { e.OldItems, e.NewItems }, null); // Call method to let it change the tabpages 
      } 
     } 
    } 

現在,我們必須創建一個助手類,它可以幫助我們跟蹤:

public class TabControlBind 
    { 
     public TabControlBind(TabControl tabControl) 
     { 
      // Create a new TabPageCollection and bind it to our tabcontrol 
      this._tabPages = new TabControl.TabPageCollection(tabControl); 
     } 

     // Fields 
     private ObservableList<TreeNodeItem> _treeNodeItems; 
     private TabControl.TabPageCollection _tabPages; 

     // Properties 
     public ObservableList<TreeNodeItem> TreeNodeItems 
     { 
      get { return _treeNodeItems; } 
      set 
      { 
       if (_treeNodeItems != value) 
       { 
        _treeNodeItems = value; 
        _treeNodeItems.OnPropertyChanged += OnPropretyChanged; 
        OnPropretyChanged(null, null); 
       } 
      } 
     } 

     public TabControl.TabPageCollection TabPages 
     { 
      get 
      { 
       return this._tabPages; 
      } 
     } 

     // Events 
     private void OnPropretyChanged(object sender, PropertyChangedEventArgs e) 
     { 
      if (sender == null) // If list got set 
      { 
       // Remove existing tabpages 
       this._tabPages.Clear(); 

       // Loop through all items inside the ObservableList object and add them to the Tabpage 
       foreach (TreeNodeItem _treeNodeItem in this._treeNodeItems) 
       { 
        TabPage tabPage = new TabPage() { Text = _treeNodeItem.Value, Tag = _treeNodeItems }; 
        this._tabPages.Add(tabPage); 
       } 
      } 
      else if (sender is object[]) // If only one (or multiple) objects have been changed 
      { 
       // Get OldItems and NewItems 
       object[] changedItems = (object[])sender; 
       // Remove OldItems 
       if (changedItems[0] != null) 
       { 
        foreach (dynamic oldItems in (IList)changedItems[0]) 
        { 
         foreach (TabPage tab in this._tabPages) 
         { 
          if (tab.Text == oldItems.Value) 
          { 
           this._tabPages.Remove(tab); 
           break; 
          } 
         } 

        } 
       } 
       // Add OldItems 
       if (changedItems[1] != null) 
       { 
        foreach (dynamic newItems in (IList)changedItems[1]) 
        { 
         TabPage tabPage = new TabPage() { Text = newItems.Value, Tag = newItems }; 
         this._tabPages.Add(tabPage); 
        } 
       } 
      } 
     } 
    } 

這是一個關於如何使用它的一個樣本:

TabControlBind tabControlBinder; 
    ObservableList<TreeNodeItem> treeNodeItems; 

    private void btnAdd_Click(object sender, EventArgs e) 
    { 
     // This will automatically update the TabControl 
     treeNodeItems.Add(new TreeNodeItem(new NTree<string>() { data = "Test3" })); 
    } 

    private void frmMain_Load(object sender, EventArgs e) 
    { 
     // Create a new list object an add items to it 
     treeNodeItems = new ObservableList<TreeNodeItem>(); 
     treeNodeItems.Add(new TreeNodeItem(new NTree<string>() { data = "Test" })); 
     treeNodeItems.Add(new TreeNodeItem(new NTree<string>() { data = "Test2" })); 

     // Create a new instance of the TabControlBind class, set it to our TabControl 
     tabControlBinder = new TabControlBind(tabControl); 
     tabControlBinder.TreeNodeItems = treeNodeItems; 
    } 
+1

此問題正在尋找一種將TabPages集合綁定到分層對象集合的方法,並讓它們得到自動生成和自動更新,而不必像這樣在代碼隱藏中手動創建標籤頁。 – Rachel

+0

再次看到我的答案plea.se –

+0

感謝您的更新。我已經刪除了我的downvote,並將進行測試,看看它是否有效。我曾經希望沒有自定義控件就可以輕鬆完成這個任務,但是看起來並不是這樣。謝謝:) – Rachel

相關問題