Home > database >  Is there a graceful way to display a big 2 dimensional array in WPF like excel?
Is there a graceful way to display a big 2 dimensional array in WPF like excel?

Time:01-21

I am working with a requirement for displaying a 2 dimensional array in a WPF window. The size of array can be up to 360*720. I have tried to use DataTable bound to a DataDrid, but it took so much time to load the grid and very RAM consuming. My example code is below.

public void SetData(double[][] array)
{   
    if(array.Length <= 0)
        return;
    DataTable table = new DataTable();
    for (int i = 0; i < array[0].Length; i  )
    {
        table.Columns.Add(i.ToString(), typeof(double));
    }
    for (int i = 0; i < array.Length; i  )
    {
        DataRow row = table.NewRow();
        for (int j = 0; j < array[i].Length; j  )
        {
            row[j] = array[i][j].ToString();
        }
        table.Rows.Add(row);
    }
    dataGrid.DataContext = table;
}

I created an array of double of which the dimension is 360 * 720 and called the SetData() method above. As a result, the RAM occupied by the program increased several GBs and very time consuming.

I wonder if there is a graceful way to solve this problem or there are some shortcomings in my code. Thank you.

CodePudding user response:

Thanks for all these useful answers and comments which helped me a lot. After doing some search, I seemed to find out the reason why my code costs so much time to render the DataGrid. I wrapped up the grid with a ScrollViewer before. I removed it and it went very well. Here is the link where I found the tip.WPF DataGrid is very slow to render.

Thank you all.

CodePudding user response:

Create a separate class that can return the enumerator as data.

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
}

You can use Listview and Gridview as Databound controls.
  
   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;
    }
  •  Tags:  
  • Related