如何将DataGrid转换为dataTable

10

我希望将所有的datagrid记录复制到datatable中,而不使用任何循环。 例如:

Dim dt as New DataTable
dt = Datagrid1.Items

但是这并没有起作用,并且显示一个错误消息。

我的开发平台是Visual Studio 2010,使用的语言是WPF和vb.net 4.0。

5个回答

18

这是一种无需使用循环即可将所有记录从DATAGRID传输到DATATABLE的方法。

VB:

Dim dt As New DataTable
dt = CType(DataGrid1.ItemsSource, DataView).ToTable

C#:

DataTable dt = new DataTable();
dt = ((DataView)DataGrid1.ItemsSource).ToTable();  

4
我在 C# 数据表格中没有找到 "ItemSource"。 - John Pasquet
1
如何使用 MVVM 进行操作 - Usman Ali

5

这取决于数据网格如何填充。如果DataContext属性设置为DataTable,则可以简单地检索此值并将其强制转换为DataTable。

没有直接的方法从DataGrid元素转换为DataTable。

如果要手动执行此操作,您需要创建一个DataTable实例,然后使用循环从DataGrid中的项创建行。


2
要将您的数据网格转换为带有标题行的数据表,您可以按照以下步骤操作:
1)创建检索单元格的方法
  static public DataGridCell GetCell(DataGrid dg, int row, int column)
    {
        DataGridRow rowContainer = GetRow(dg, row);

        if (rowContainer != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null)
            {
                dg.ScrollIntoView(rowContainer, dg.Columns[column]);
                cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            }
            return cell;
        }
        return null;
    }

2) 遍历所有项目并将内容传递给数据表格的“cell”

    private void DataGridToDataTable()
    {
        DataTable dt = new DataTable();
        var j = byte.MinValue;//header row handler
        dt.Rows.Add();
        foreach (DataGridColumn column in dataGrid1.Columns)
        {                
            dt.Columns.Add(column.GetValue(NameProperty).ToString());
            dt.Rows[byte.MinValue][j++] = column.Header;
        }

        //data rows handler
        for (int i = byte.MinValue ; i < dataGrid1.Items.Count; i++)
        {
            dt.Rows.Add();
            for (j = Byte.MinValue; j < dataGrid1.Columns.Count; j++)
            {
                DataGridCell dgc = GetCell(dataGrid1, i, j);
                dt.Rows[i + 1][j] =  ((dgc.Content) as TextBlock).Text;
            }
        }
    }  

请注意,在使用这些方法时,您必须将其引用到代码中。

using System.Windows.Media;
using System.Data;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

这里提供一个帮助类以供使用。

 /// <summary>
/// Class to help to retrive the Data Grid Contain
/// </summary>
public static class DataGridHelper
{
    /// <summary>
    /// Retrive the cell contains
    /// </summary>
    /// <param name="dg">DataGrid</param>
    /// <param name="row">row</param>
    /// <param name="column">column</param>
    /// <returns>DataGrid Cell content</returns>
    static public DataGridCell GetCell(DataGrid dg, int row, int column)
    {
        DataGridRow rowContainer = GetRow(dg, row);

        if (rowContainer != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);

            // try to get the cell but it may possibly be virtualized
            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null)
            {
                // now try to bring into view and retreive the cell
                dg.ScrollIntoView(rowContainer, dg.Columns[column]);
                cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            }
            return cell;
        }
        return null;
    }
    /// <summary>
    /// Get row content
    /// </summary>
    /// <param name="dg">Datagrid</param>
    /// <param name="index">Index</param>
    /// <returns>DataGridRow</returns>
    static public DataGridRow GetRow(DataGrid dg, int index)
    {
        DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        {
            // may be virtualized, bring into view and try again
            dg.ScrollIntoView(dg.Items[index]);
            row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
        }
        return row;
    }
    static T GetVisualChild<T>(Visual parent) where T : Visual
    {
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        {
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v as T;
            if (child == null)
            {
                child = GetVisualChild<T>(v);
            }
            if (child != null)
            {
                break;
            }
        }
        return child;
    }
}

我已经成功地让它工作了,但是我不得不添加自己的GetVisualChild和GetRow方法,因为它们在这里没有发布。 - AndrewBenjamin
抱歉,我忘了,但是像你所看到的那样,创建自己的检索行和获取可视子项的方法很容易。如果您需要,让我知道我是否也应该发布这些方法。 - luka
你能添加这些方法使答案完整吗? - Jeremy Morren
嗨Jeremy,我添加了辅助类,希望这可以帮到你。 - luka

0

我刚刚测试了一下,这个可以用

Dim dt as New DataTable
dt = ctype(Datagrid1.Datasource, DataTable)

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接