将数组的数组或动态绑定到数据网格

本文关键字:数组 数据 数据网 网格 动态绑定 | 更新日期: 2023-09-27 18:01:37

我正在尝试将数组的数组绑定到DataGrid

我知道我可以通过将数据转换为DataTable然后绑定它来相当容易地做到这一点。但这不是我需要的,因为我需要能够通过PagedCollectionVIew向数据添加分组。

这样做的原因是:我有一组为文档创建结构的控件,我想在使用结构控件时动态地用虚拟数据反映这个结构。虚拟数据是一个简单的随机整数对称矩阵,其中行是数据元素,我想将每个网格列绑定到数组的元素,而不是数组对象。

_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!这里真的需要一些帮助。

将数组的数组或动态绑定到数据网格

我有答案了(好吧,我很久以前就有了,但我记得我发布了这个问题)。这是一个来自无数片段和我自己大脑的弗兰肯密码怪物,所以我不能把每个人都归为自己。我要把它挂起来。因为我觉得这太棒了。即使没人在乎:

它使用:- DLR-一点反思-一点IL建设。

也许应该把这些都放到某个地方的博客文章中,但是我没有开博客。

这段代码为ViewModel调用的视图创建数据。

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