在DataGrid中显示2d数组

时间:2010-12-16 12:52:56

标签: .net wpf data-binding wpfdatagrid

我正在尝试让DataGrid显示object[][]的内容。这将是只读的,因此我不关心通知更改或类似的事情。将ItemSource设置为object[][]只会在网格中显示Array的属性,而使用List<List<object>>代替相同的操作,这显然无益。

每个1d阵列中的列数可以是任意的;我只想为每行中的每个数组元素创建一个未命名的列。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

请参阅this question中的答案。这也可以编辑值。由于您只想展示它们,如果不需要使用DataGrid,可能更容易使用 Jobi Joy 的答案。

从该问题做出答案的简短版本。你需要一个Ref类

public class Ref<T>
{  
    private readonly Func<T> getter;   
    private readonly Action<T> setter;  
    public Ref(Func<T> getter, Action<T> setter)   
    {   
        this.getter = getter;   
        this.setter = setter;   
    }  
    public T Value { get { return getter(); } set { setter(value); } }   
}  

一个辅助类,用于从二维数组中获取动态列

public class BindingHelper
{
    public DataView GetBindable2DViewFromIList<T>(IList list2d)
    {
        DataTable dataTable = new DataTable();
        for (int i = 0; i < ((IList)list2d[0]).Count; i++)
        {
            dataTable.Columns.Add(i.ToString(), typeof(Ref<T>));
        }
        for (int i = 0; i < list2d.Count; i++)
        {
            DataRow dataRow = dataTable.NewRow();
            dataTable.Rows.Add(dataRow);
        }
        DataView dataView = new DataView(dataTable);
        for (int i = 0; i < list2d.Count; i++)
        {
            for (int j = 0; j < ((IList)list2d[i]).Count; j++)
            {
                int a = i;
                int b = j;
                Ref<T> refT = new Ref<T>(() => (list2d[a] as IList<T>)[b], z => { (list2d[a] as IList<T>)[b] = z; });                    
                dataView[i][j] = refT;
            }
        }
        return dataView;
    }
}

之后你可以像这样使用ItemsSource

<DataGrid Name="dataGrid" 
          RowHeaderWidth="0" 
          ColumnHeaderHeight="0" 
          AutoGenerateColumns="True" 
          AutoGeneratingColumn="dataGrid_AutoGeneratingColumn"/> 

dataGrid.ItemsSource = BindingHelper.GetBindable2DViewFromIList<object>(m_2DArray);

private void dataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
{ 
    DataGridTextColumn column = e.Column as DataGridTextColumn; 
    Binding binding = column.Binding as Binding; 
    binding.Path = new PropertyPath(binding.Path.Path + ".Value");
}