在 DataGrid 中显示二维数组

发布于 2024-10-08 02:37:25 字数 292 浏览 3 评论 0 原文

我正在尝试让 DataGrid 显示 object[][] 的内容。这将是只读的,所以我不关心通知更改或类似的事情。将 ItemSource 设置为 object[][] 只是在网格中显示 Array 的属性,并使用 List ;> 却做了同样的事情,这显然没有帮助。

每个一维数组的列数可以是任意的;我只是想为每行中的每个数组元素创建一个未命名的列。我该怎么做?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅浅 2024-10-15 02:37:25

请参阅我的答案 这个问题。这也将允许编辑值。由于您只是对显示它们感兴趣,如果不需要使用 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");
}

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");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文