在WPF中动态生成GridView绑定

时间:2011-07-05 20:28:20

标签: c# wpf gridview ado.net binding

我的老板喜欢发明非常不寻常的场景来编码,这个让我难过。我正在制作一个必须使用GridView来显示一些非常晚的数据的WPF应用程序。 为了显示数据,他希望能够首先使用一些列标题初始化GridView,这不是问题。然后,他需要将这个GridView,一个DataTable和一些格式信息传递给一个绑定数据的方法。

在设计时,我们不知道我们想要绑定到DataTable中的哪些列。我们不能使用XAML,因为整个网格是动态创建的。在绑定数据时,我们必须指定每列格式化数据。到目前为止,我实现了IValueConverter的实现,它将格式化类作为其构造函数中的参数。 最后的转折是它必须支持多次在数据表中显示相同的列,以不同的方式格式化。显然,您不能在一个DataTable中拥有多个列的副本,因为它们具有名称冲突。

这是我到目前为止所拥有的:

    /// <summary>
    /// Sets the view of the passed ListView to a new GridView with properly formatted headers.
    /// The headers are also the field names (column names) of the data table that you will
    /// bind to
    /// </summary>
    /// <param name="displayPanel"></param>
    /// <param name="displayFieldList"></param>
    public static void InitializeGrid(ListView displayPanel,IDisplayFieldList displayFieldList)
    {


        GridView gv = new GridView();
        gv.AllowsColumnReorder = true;

        for (int i = 0; i < displayFieldList.Count; i++)
        {
            GridViewColumn col = new GridViewColumn();
            col.Header = displayFieldList[i].HeaderText;

            gv.Columns.Add(col);
        }

        displayPanel.View = gv;
    }

    /// <summary>
    /// Binds data to the columns set in the ListView.View.  Displays and formats the data.
    /// </summary>
    /// <param name="displayPanel"></param>
    /// <param name="table"></param>
    /// <param name="displayFieldList"></param>
    public static void BindData(ListView displayPanel, DataTable table, IDisplayFieldList displayFieldList)
    {
        for(int i=0; i<displayFieldList.Count; i++)
        {
            GridViewColumn gridCol = ((GridView)displayPanel.View).Columns[i];

            DmlDisplayField displayField = displayFieldList[i] as DmlDisplayField;
            if(displayField != null)
            {
                gridCol.DisplayMemberBinding = new Binding()
                {
                    Source = table.Columns[displayField.DataField],
                    Converter = new MaskConverter(displayField.DataField),
                    ConverterParameter = displayField
                };
            } 
            else
            {
                gridCol.DisplayMemberBinding = new Binding()
                {
                    Source = table.Columns[displayFieldList[i].Name]
                };
            }
        }
        displayPanel.ItemsSource = table.AsDataView();
    }

IDisplayFieldList是包含元数据的DisplayField或DmlDisplayField类的集合。 MaskConverter是一个IValueConverter,它以各种方式格式化DmlDisplayField列。

当我运行此代码时,所有行都是空白的,但我可以选择单独的行。

到目前为止,我已经尝试了许多不同的绑定方式,并且大多数从System.Reflection给出了一个“模糊匹配异常”。

如果你需要我发布MaskConverter,我会,但它很乱......

有什么想法吗?万分感谢!

1 个答案:

答案 0 :(得分:0)

我只使用winforms DataGridView做了类似的事情,但我认为wpf GridView也应该能够动态地自动创建它的列......

ICustomTypeDescriptor接口允许您向网格提供自己的一组PropertyDescriptors。没有必要将两列绑定到同一属性(描述符),因为您可以为同一属性/列/字段/无论如何提供2个不同的属性描述符...

另一方面,这个概念可能有点矫枉过正,可能有更简单的方法来做到这一点,所以这只是一个建议