2010-06-17 41 views
18

Tôi đang tìm kiếm cách tạo các cột của DataGrid từ công cụ DynamicKit theo cách MvvM. Nhưng có vẻ như nó là không thể!WPF MvvM DataGrid Dynamic Columns

Có một số thiết bị phải thực hiện lấy mẫu không?

không cần phải tạo điều khiển người dùng hoặc điều khiển khác đến từ DataGrid, tôi chỉ muốn đặt de ItemSource của lưới vào đối tượng tùy chỉnh của mình và trong một số điểm tôi muốn xác định cột của lưới trong thời gian chạy động dựa vào loại đối tượng.

Điều đó có khả thi không?

cổ vũ

Trả lời

9

Tôi sẽ mở đầu này bằng cách nói rằng nó có thể không phải là giải pháp tốt nhất để được làm và không thể làm việc trong một số tình huống, nhưng bạn có thể cung cấp cho nó một thử và xem nếu nó sẽ làm việc cho bạn muốn gì. Tôi chỉ đánh nó lên để nó có thể có một số lỗi trong đó. Nó vẫn sẽ liên quan đến một số mã, nhưng nó giữ mô hình của bạn không biết về bạn xem.

Những gì bạn cần làm là tạo thuộc tính tiện ích mở rộng cho phép bạn liên kết thuộc tính Cột trên DataGrid. Đây là một ví dụ mà tôi đặt lại với nhau.

using System.Collections.ObjectModel; 
using System.Collections.Specialized; 
using System.Windows; 
using System.Windows.Controls; 

public static class DataGridExtension 
{ 
    public static ObservableCollection<DataGridColumn> GetColumns(DependencyObject obj) 
    { 
     return (ObservableCollection<DataGridColumn>)obj.GetValue(ColumnsProperty); 
    } 

    public static void SetColumns(DependencyObject obj, ObservableCollection<DataGridColumn> value) 
    { 
     obj.SetValue(ColumnsProperty, value); 
    } 

    public static readonly DependencyProperty ColumnsProperty = 
      DependencyProperty.RegisterAttached("Columns", 
      typeof(ObservableCollection<DataGridColumn>), 
      typeof(DataGridExtension), 
      new UIPropertyMetadata (new ObservableCollection<DataGridColumn>(), 
      OnDataGridColumnsPropertyChanged)); 


    private static void OnDataGridColumnsPropertyChanged(
      DependencyObject d, 
      DependencyPropertyChangedEventArgs e) 
    { 
     if (d.GetType() == typeof(DataGrid)) 
     { 
      DataGrid myGrid = d as DataGrid; 

      ObservableCollection<DataGridColumn> Columns = 
       (ObservableCollection<DataGridColumn>)e.NewValue; 

      if(Columns != null) 
      { 
       myGrid.Columns.Clear(); 

       if (Columns != null && Columns.Count > 0) 
       { 
        foreach (DataGridColumn dataGridColumn in Columns) 
        { 
         myGrid.Columns.Add(dataGridColumn); 
        } 
       } 


       Columns.CollectionChanged += delegate(object sender, 
           NotifyCollectionChangedEventArgs args) 
        { 
         if(args.NewItems != null) 
         { 
         foreach (DataGridColumn column 
           in args.NewItems.Cast<DataGridColumn>()) 
         { 
          myGrid.Columns.Add(column); 
         } 
         } 

         if(args.OldItems != null) 
         { 
         foreach (DataGridColumn column 
           in args.OldItems.Cast<DataGridColumn>()) 
         { 
          myGrid.Columns.Remove(column); 
         } 
         } 
        }; 
      } 
     } 
    } 
} 

Sau đó, bạn gắn nó vào bạn DataGrid như thế này (Nơi cột là tài sản một ObservableCollection trên mô hình quan điểm của bạn)

<Controls:DataGrid AutoGenerateColumns="False" 
      DataGridExtension.Columns="{Binding Columns}" /> 

Tôi không chắc chắn như thế nào nó sẽ trả lời nếu bạn bắt đầu thêm và xóa các cột, nhưng dường như nó hoạt động từ thử nghiệm cơ bản của tôi. Chúc may mắn!

+1

Mã trên sẽ thực hiện công việc trong trường hợp chung. Tuy nhiên, nó sẽ thất bại khi bạn ẩn DataGrid và làm cho nó hiển thị một lần nữa. Bởi vì các thuộc tính cột sẽ hiển thị rằng có 0 cột khi chúng được ẩn và khi thuộc tính cột được thay đổi, cuộc gọi lại sẽ được kích hoạt và nó sẽ cố gắng thêm cột một lần nữa, nhưng cột vật lý không tồn tại trong datagrid để mã sẽ thất bại với một ngoại lệ nói rằng không thể thêm các cột trùng lặp. –

1

Có vấn đề tương tự, tôi không muốn thêm thuộc tính phụ thuộc khác. Cách giải quyết của tôi là tổ chức dữ liệu để hiển thị trong DataGrid trong một DataTable và liên kết thuộc tính DataGrid ItemSource với DataTable này (với tất nhiên các AutoGenerateColumn được đặt thành true).

Nó hoạt động tốt, DataGrids có vẻ hài lòng với DataTable là nguồn.

+0

DataGrid.ItemSource không chấp nhận một DataTable. Nó nói rằng đó là không có một IEnumerable ... (. Net 4.5) –

+0

Tôi xây dựng dự án với 4,5 và nó đã không cho tôi bất kỳ lỗi. Tôi ràng buộc các mục nguồn của datagrid trong xaml: 'ItemsSource =" {Binding ResultsViewerValues} "', trong đó ResultViewerValues ​​là thuộc tính (DataTable) trong mô hình khung nhìn – user3189858