2012-08-30 75 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

相关问题