【问题标题】:How to convert DataGrid to dataTable如何将 DataGrid 转换为 dataTable
【发布时间】:2014-03-16 15:30:37
【问题描述】:

我想在不使用任何循环的情况下将所有数据网格记录复制到数据表中。 例如:

Dim dt as New DataTable
dt = Datagrid1.Items

但这不起作用并给出错误消息。

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

【问题讨论】:

    标签: wpf vb.net wpfdatagrid wpf-4.0


    【解决方案1】:

    这是在不使用 LOOP 的情况下将所有记录从 DATAGRID 传输到 DATATABLE 的方法。

    VB:

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

    C#:

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

    【讨论】:

    • 我在 C# 数据网格上找不到“ItemSource”
    • 如何用 mvvm 来做
    【解决方案2】:

    这取决于数据网格的填充方式。如果 DataContext 属性设置为 DataTable,那么您只需检索该值并强制转换为 DataTable。

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

    如果您想手动执行此操作,则必须创建 DataTable 的实例,然后使用循环从 DataGrid 中的项目创建行。

    【讨论】:

      【解决方案3】:

      要将您的 dataGrid 转换为带有标题行的数据表,您可以按照以下步骤操作:

      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) 遍历所有项目并将内容传递给数据表“单元格”

          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 方法,因为它们没有发布在这里。
      • 抱歉忘记了,但就像您看到的,创建自己的方法来检索行和 GetVisulaChild 很容易。让我知道你是否想要我也发布了这个方法
      • 能不能把这些方法加进去,让答案完整?
      • 嗨,杰里米,我添加了助手类,希望对您有所帮助
      【解决方案4】:

      我刚刚测试了这个,它可以工作

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

      【讨论】:

        【解决方案5】:

        您必须在 DataGrid 上循环并将项目添加到 Datatable。下面的链接可能会有所帮助。

        DataGridView selected rows to DataTable

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多