I'm trying to get a DataGrid to display the contents of an object[][]
. This'll be read-only so I don't care about notification changes or anything like that. Setting ItemSource
to an object[][]
simply displays the properties of Array
in the grid, and using List<List<object>>
instead does the same, which is decidedly unhelpful.
The number of columns in each 1d array can be arbitary; I simply want an unnamed column to be created for each array element in each row. How can I 开发者_开发知识库do this?
See my answer in this question. This will also enable editing of the values. Since you're just interested in displaying them it might be easier to use the answer from Jobi Joy if using the DataGrid isn't a requirement.
To make a short version of the answer from that question. You'll need a Ref class
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); } }
}
And a helper class to get dynamic columns from the 2d array
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;
}
}
After that you can use ItemsSource like this
<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");
}
精彩评论