2012-08-30 6 views
13

私は初めてのWindowsフォームプロジェクトを試みています。以前は完全にWebベースであり、いくつかの問題が発生していました。私は、TabControlにオブジェクトのリストをバインドし、タブを作成して、各タブのクリックイベントからアクセス可能なデータバインドされた値を持つようにします。データをWindowsフォームにバインドTabControl

Iが結合したいだオブジェクトが

public class TreeNodeItem 
{ 
    private NTree<string> node; 

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

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

あるNTreeノードは、ツリー構造のモデルデータオブジェクト内のノードを表します。 Tab TextプロパティにバインドされているValueプロパティで、リスト内の各オブジェクトのタブを作成したいとします。他の投稿にはコントロールのItemsSourceプロパティへのバインディングが記述されていますが、Visual Studioはこのプロパティを与えません。

ご協力いただきますようお願い申し上げます。

乾杯

はスチュワートは

+2

私がした各時間をそのような状況に遭遇した場合、私はカスタムコントロールを作成するか(5年間の開発作業中に1つも見なかった)、あるいはデータを表現する別の方法を見つけるでしょう。 Ex。 treeListコントロール – Marty

+0

これは、winformsの代わりに 'WPF'を使用していた場合、世界で最も簡単なことです。 winformsで規定されていない場合は、代わりにWPFを使用することをお勧めします。私はしばしばビュー・モデルでタブとタブ・ページの内容にデータ・バインディングを行いました。 wpfがオプションである場合、私は例を提供することができます。 –

+0

@NathanA私はWPFを使用していたのですが、これはとても簡単なので、私はWinFormsを使用することに固執しています。 – Rachel

答えて

2

さて、私は結合が必須だったことを知りませんでした。 Windows Formsアプリケーションでこのようなことが起こったことはありませんでしたが、これを行うクラスを作成することにしました。

オブジェクト/プロパティがそのリスト内で変更されたかどうかを追跡するために、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

関連する問題