2013-02-28 51 views
0

我試圖數組的數組綁定到DataGrid陣列的結合陣列或動態的數據網格

我知道我可以將數據轉換爲一個DataTable,然後綁定,這樣做很容易。但這不是我所需要的,因爲我需要通過PagedCollectionVIew將數據分組添加到數據中。

這樣做的原因是這樣的:我有一組爲一個文件創建一個結構控制,我想在正在使用該結構的控制,以反映這種結構與動態虛擬數據。虛擬數據是一個隨機整數的簡單對稱矩陣,其中行是數據元素,我想將每個網格列綁定到數組的elemtns,而不是數組對象。

_dataGenerator = new DummyDataGenerator(); 
_dummyDataView = new ObservableCollection<int[]>(); 
DummyData = new PagedCollectionView(_dummyDataView); 

_dummyDataView

// Set up the dummy data for the fields available. 
_dataGenerator.CreateData(ReportFields).ForEach(_dummyDataView.Add); 

填充和XAML只是一個DataGrid結合DummyData ...然後我會動態地添加分組和分類法,以作爲用戶與播放文檔數據。我到處搜索,但找不到解決方案,但必須有一種方法(必須有人寫博客)綁定到xaml中的數組元素!真的需要一些幫助。

+0

我在下面回答我自己的問題。這應該可能是一篇博客文章,因爲參與此事的每個人都是我。但是那裏有一些非常有用的片段。值得一讀,我猜。 – tigerswithguitars 2013-03-12 15:27:30

+0

嘿,過去我......你可以使用ExpandoObject而不是創建一個新類型? http://blogs.msdn.com/b/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx – tigerswithguitars 2013-12-12 10:17:48

回答

1

我有答案(當然我是有年代久遠,但我記得我張貼了這個問題)。這是一個來自幾十億片斷和我自己大腦的破解代碼怪物,所以我不能將每個人歸因於它。我打算放棄它。因爲我覺得這很棒。即使沒有人關心:

它的用途: - DLR - 一點反思 - 一點IL建設。

也許應該將所有這一切都爲博客文章的地方,但我不保持一個博客。

這是用於由視圖模型稱爲視圖創建數據的代碼。

public IEnumerable<dynamic> CreateData(ObservableCollection<ReportFieldVm> reportFields) 
    { 
     // Find the length of the array. 
     var size = reportFields.Count; 

     // Create matrix. 
     var b = new int[size, size]; 

     // Random for the values. 
     var rand = new Random((int)DateTime.Now.Ticks); 

     // Build the symmetric matrix. 
     for (var i = 0; i < size; i++) 
     { 
      for (var j = 0; j < size; j++) 
      { 
       if (i == j) 
       { 
        b[i,j] = rand.Next(0, 100); 
       } 
       else 
       { 
        var a = rand.Next(0, 100); 
        b[i,j] = a; 
        b[j,i] = a; 
       } 
      } 
     } 

     // Define the assembly to add out new type to. 
     var asmName = new AssemblyName("DummyAssembly"); 
     var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run); 
     var mb = ab.DefineDynamicModule("DummyModule"); 

     // Define our type. 
     var d = mb.DefineType("DummyType", TypeAttributes.Public); 

     const MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; 

     // Define all the fields for the new type. 
     foreach (var rf in reportFields.OrderBy(rf => rf.SelectOrder)) 
     { 
      var propertyName = rf.FieldName; 

      var field = d.DefineField("m_" + propertyName, typeof(int), FieldAttributes.Private); 

      var property = d.DefineProperty(propertyName, PropertyAttributes.HasDefault, typeof(int), null); 

      var dGetAccessor = d.DefineMethod("get_" + propertyName, GetSetAttr, typeof(int), Type.EmptyTypes); 

      var numberGetIl = dGetAccessor.GetILGenerator(); 
      numberGetIl.Emit(OpCodes.Ldarg_0); 
      numberGetIl.Emit(OpCodes.Ldfld, field); 
      numberGetIl.Emit(OpCodes.Ret); 

      var dSetAccessor = d.DefineMethod("set_" + propertyName, GetSetAttr, null, new Type[] { typeof(int) }); 
      var numberSetIl = dSetAccessor.GetILGenerator(); 
      numberSetIl.Emit(OpCodes.Ldarg_0); 
      numberSetIl.Emit(OpCodes.Ldarg_1); 
      numberSetIl.Emit(OpCodes.Stfld, field); 
      numberSetIl.Emit(OpCodes.Ret); 

      property.SetGetMethod(dGetAccessor); 
      property.SetSetMethod(dSetAccessor); 
     } 

     // Create the type. 
     var dummyType = d.CreateType(); 

     var array = new List<dynamic>(); 

     // Convert the matrix into the array of the dynamic. 
     for (var i = 0; i < size; i++) 
     { 
      var obj = Activator.CreateInstance(dummyType); 
      int j = 0; 
      foreach (var rf in reportFields.OrderBy(rf => rf.SelectOrder)) 
      { 
       var type = obj.GetType(); 
       var prop = type.GetProperty(rf.FieldName); 
       prop.SetValue(obj, b[j, i], null); 
       j++; 
      } 
      array.Add(obj); 
     } 

     return array; 
    } 

這是綁定在視圖中調用的視圖的代碼。

其中:

  1. _dynamicReportPreview是在XAML命名的網格。

  2. ViewModel是公開在視圖構造函數中設置視圖的DataContext的屬性。

    private void BuildPreviewGridColumns() 
    { 
        if (_dynamicReportPreview == null) 
         return; 
    
        _dynamicReportPreview.Columns.Clear(); 
    
        var initialFields = ViewModel.ReportFields.OrderBy(rf => rf.SelectOrder); 
    
        foreach (var rf in initialFields) 
        { 
         var col = new Column 
         { 
          ColumnName = rf.FieldName, 
          Binding = new Binding(rf.FieldName) 
         }; 
    
         _dynamicReportPreview.Columns.Add(col); 
    
         if (!rf.IsVisible) 
         { 
          col.Visible = false; 
         } 
        } 
    }