65.9K
CodeProject 正在变化。 阅读更多。
Home

如何将 2D 数组绑定到 WPF 中的 ListView?

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (6投票s)

2010年3月19日

CPOL

1分钟阅读

viewsIcon

48452

downloadIcon

1046

将 2D 数组绑定到 WPF ListView 的 2 种解决方案

binding_2d_array_listview.png

引言

WPF 绑定非常有用且强大。您可以将任何内容绑定到 ItemsControl.ItemsSource,该控件继承自 IEnumerable 接口,例如一维数组、List<T>Collection<T> 等。但它无法绑定二维数组。如果您绑定多维数组(例如二维数组),则会显示异常“数组不是一维数组”。

解决方案 1:转换为继承自 IEnumerable 接口的类,例如 DataTable,然后将其绑定到 ListView

许多类都继承自 IEnumerable,例如 List<T>Collection<T>Dictionary<Key, Value> 等。在此解决方案中,我计划将其转换为 DataTable 以供通用使用。

首先准备一个二维数组,我们生成了一个 100000 * 6 的二维数组。

double[,] data = new double[100000, 6];
for (int i = 0; i < data.GetLength(0); i++)
{
    data[i, 0] = i + 1;
    for (int j = 1; j < data.GetLength(1); j++)
    {
        data[i, j] = j + 1;
    }
}

我们将此数组转换为 DataTableDataTable 的列数应等于数组的第二个维度长度,在本示例中为 6。

private DataTable Convert2DArrayToDataTable(double[,] data, string[] columnNames)
{
    int len1d = data.GetLength(0);
    int len2d = data.GetLength(1);
    Check2DArrayMatchColumnNames(data, columnNames);

    DataTable dt = new DataTable();
    for (int i = 0; i < len2d; i++)
    {
        dt.Columns.Add(columnNames[i], typeof(double));
    }

    for (int row = 0; row < len1d; row++)
    {
        DataRow dr = dt.NewRow();
        for (int col = 0; col < len2d; col++)
        {
            dr[col] = data[row, col];
        }
        dt.Rows.Add(dr);
    }

    return dt;
}

private void Check2DArrayMatchColumnNames(double[,] data, string[] columnNames)
{
    int len2d = data.GetLength(1);

    if (len2d != columnNames.Length)
    {
        throw new Exception("The second dimensional length must equals column names.");
    }
}

列名是什么?我们将其用作 DataTable 中的字段名。在调试时,这很有用,您可以在 DataView 中查看 DataTable 。接下来,我们初始化 ListView 视图和列。

private void Binding2DArrayToListView
	(ListView listview, double[,] data, string[] columnNames)
{
    Check2DArrayMatchColumnNames(data, columnNames);

    DataTable dt = Convert2DArrayToDataTable(data, columnNames);

    GridView gv = new GridView();
    for (int i = 0; i < data.GetLength(1); i++)
    {
        GridViewColumn col = new GridViewColumn();
        col.Header = columnNames[i];
        col.DisplayMemberBinding = new Binding("[" + i + "]");
        gv.Columns.Add(col);
    }

    lvwArray.View = gv;
    lvwArray.ItemsSource = dt.Rows;
}

现在完成了。但是,这种需要转换的解决方案存在性能问题。如果数组较大,则转换将需要很长时间。无论转换为任何类型。更好的解决方案是什么?请继续阅读解决方案 2。

解决方案 2:编写数组访问器,然后将其绑定到 ListView

解决方案 1 和解决方案 2 之间的最大区别在于,解决方案 1 需要转换过程。但解决方案 2 不需要。我们编写一个数组访问器来访问数组。以下是代码

class ArrayVisitor : IEnumerable<double[]>
{
    private double[,] _data;

    public ArrayVisitor()
    {
    }

    public ArrayVisitor(double[,] data)
    {
        _data = data;
    }

    public double[,] Data
    {
        get { return _data; }
        set { _data = value; }
    }

    #region IEnumerable<double[]> Members

    public IEnumerator<double[]> GetEnumerator()
    {
        if (_data == null)
            throw new ArgumentException("Data cannot be null.", "Data");

        int len2d = _data.GetLength(1);

        for (int i = 0; i < _data.GetLength(0); i++)
        {
            double[] arr = new double[len2d];
            for (int j = 0; j < len2d; j++)
            {
                arr[j] = _data[i, j];
            }

            yield return arr;
        }
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    #endregion
}

如何在代码中使用它?

private void Bindng2DArrayToListview2
	(ListView listview, double[,] data, string[] columnNames)
{
    Check2DArrayMatchColumnNames(data, columnNames);

    GridView gv = new GridView();
    for (int i = 0; i < data.GetLength(1); i++)
    {
        GridViewColumn col = new GridViewColumn();
        col.Header = columnNames[i];
        col.DisplayMemberBinding = new Binding("[" + i + "]");
        gv.Columns.Add(col);
    }

    ArrayVisitor arrayVisitor = new ArrayVisitor(data);
    listview.View = gv;
    listview.ItemsSource = arrayVisitor;
}

享受代码吧!

历史

  • 2010年3月19日:初始发布
© . All rights reserved.