2012-08-30 63 views
13

Tôi đang thử dự án Windows Form đầu tiên của mình, đã hoàn toàn dựa trên web trước đó và gặp một số vấn đề. Tôi muốn ràng buộc một danh sách các đối tượng để một TabControl và có điều này tạo ra các Tabs và sau đó có một giá trị databound truy cập từ các sự kiện click của mỗi tab.Liên kết dữ liệu với Windows Form TabControl

Các đối tượng tôi muốn để ràng buộc là

public class TreeNodeItem 
{ 
    private NTree<string> node; 

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

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

Nút NTree đại diện cho một nút trong một đối tượng mà mô hình dữ liệu trong cấu trúc cây. Tôi muốn tạo một tab cho từng đối tượng trong danh sách với thuộc tính Giá trị bị ràng buộc với thuộc tính Tab Text. Các bài viết khác đề cập đến ràng buộc với thuộc tính ItemsSource của điều khiển, nhưng Visual Studio không cho tôi thuộc tính này.

Mọi trợ giúp sẽ được đánh giá cao.

Cheers

Stewart

+2

Mỗi lần tôi đã gặp phải tình huống như vậy, tôi sẽ hoặc là xây dựng một điều khiển tùy chỉnh (không nhìn thấy một trong số các hộp trong 5 năm của tôi làm việc dev) hoặc tìm một cách khác để đại diện cho dữ liệu. Ví dụ treeList control – Marty

+0

Đây là điều dễ nhất để làm trong thế giới ... nếu bạn đang sử dụng 'WPF' thay vì' winforms'. Nếu bạn không được trao giải winform, tôi khuyên bạn nên sử dụng WPF. Tôi thường thực hiện các ràng buộc dữ liệu cho các tab và nội dung trang tab với các kiểu xem của tôi. Tôi có thể cung cấp một ví dụ nếu wpf là một lựa chọn. –

+0

@NathanA Tôi biết, tôi ước tôi đã sử dụng WPF vì điều này sẽ dễ dàng như vậy nếu tôi, tuy nhiên tôi đang mắc kẹt với việc sử dụng WinForms – Rachel

Trả lời

2

Được rồi, tôi đã không biết rằng ràng buộc là bắt buộc. Mặc dù tôi chưa bao giờ thấy một cái gì đó như thế này được thực hiện trong một ứng dụng Windows Forms, tôi đã quyết định tạo ra một lớp làm điều này cho chúng ta.

Sử dụng ObservableCollection<T> để theo dõi xem một đối tượng/thuộc tính đã được thay đổi trong danh sách của nó hay chưa.

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 
      } 
     } 
    } 

Bây giờ, chúng ta phải tạo ra một lớp helper giúp chúng ta theo dõi:

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

Đây là một mẫu về cách sử dụng nó:

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

Câu hỏi này đang tìm cách để * liên kết * bộ sưu tập TabPages với một tập hợp các đối tượng phân cấp và có chúng tự động tạo và tự động cập nhật, thay vì phải tạo trang tab theo cách thủ công trong đoạn mã như sau. – Rachel

+0

Xem câu trả lời của tôi một lần nữa xin vui lòng –

+0

Cảm ơn bạn đã cập nhật. Tôi đã xóa bỏ phiếu giảm giá của mình và sẽ kiểm tra xem liệu nó có hoạt động hay không sau này. Tôi đã hy vọng sẽ có một cách dễ dàng để hoàn thành điều này mà không cần điều khiển tùy chỉnh, tuy nhiên nó trông như thế sẽ không xảy ra. Cảm ơn :) – Rachel

Các vấn đề liên quan