【问题标题】:WPF How to convert from DataGrid to DataTable?WPF 如何从 DataGrid 转换为 DataTable?
【发布时间】:2016-05-29 21:46:57
【问题描述】:

您好,我关注这个guide 是为了了解如何使用 DataGrid。

我遇到的问题是如何将 DataGrid 中的数据转换为 DataTable?

我正在尝试使用的代码是:

DataTable dt = ((DataView)dg.ItemsSource).ToTable();

但它给了我一个错误说明:

无法转换类型的对象 'System.Collections.Generic.List`1[WPFProject.Person]' 输入 'System.Data.DataView'。

我的代码与示例非常相似,除了我使用 Person 类而不是 user 并且我创建了 Person 类型的列表以便将数据插入到数据网格中。

public class Person
    {
        public bool CheckBox { get; set; }
        public int ID { get; set; }
        public string Name { get; set; }
    }

谢谢。

【问题讨论】:

    标签: wpf datatable casting datagrid


    【解决方案1】:

    你不能那样转换它。只有当您的DataGridItemSource 不是DataView 时,您的代码才有效。您需要明确地编写代码(您可以轻松地将任何 collection<T> 谷歌搜索到 DataTable)将您的 collection 转换为 DataTable。看看下面的例子:

    XAML

      <StackPanel>
        <DataGrid ItemsSource="{Binding list}" x:Name="myGrid"/>
        <Button Content="convert back" Click="Button_Click_1" />
    </StackPanel>
    

    逻辑:

    private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            var list = new List<MyClass>(myGrid.ItemsSource as IEnumerable<MyClass>);
            var dataTable = ToDataTable(list);
            if (dataTable != null)
            {
    
            }
        }
    
        public static DataTable ToDataTable<T>(List<T> items)
        {
            DataTable dataTable = new DataTable(typeof(T).Name);
    
            //Get all the properties
            PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo prop in Props)
            {
                //Setting column names as Property names
                dataTable.Columns.Add(prop.Name);
            }
            foreach (T item in items)
            {
                var values = new object[Props.Length];
                for (int i = 0; i < Props.Length; i++)
                {
                    //inserting property values to datatable rows
                    values[i] = Props[i].GetValue(item, null);
                }
                dataTable.Rows.Add(values);
            }
            //put a breakpoint here and check datatable
            return dataTable;
        }
    

    输出

    【讨论】:

      【解决方案2】:

      将 DataGrid 转换为 DataTable

      1.DataGrid Itemsource与CandidateClass列表绑定。

      2.从DataGrid的Itemsource中获取Item,然后序列化为Json,反序列化为DataTable。

        var Item = ListDataGrid.ItemsSource as IList<CandidateClass>;
        var json = JsonConvert.SerializeObject(Item);
        DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
      

      注意:如果DataGrid是基于类对象的列表形成的。这个方法很有帮助。

      【讨论】:

      • 使用NewtonSoft.Json;//对对象进行序列化和反序列化
      【解决方案3】:

      复制过去的方法1

      public static DataTable DataGridtoDataTable(DataGrid dg)
              {
      dg.SelectAllCells();
                  dg.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
                  ApplicationCommands.Copy.Execute(null, dg);
                  dg.UnselectAllCells();
                  String result = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
                  string[] Lines = result.Split(new string[] { "\r\n", "\n" }, 
                  StringSplitOptions.None);
                  string[] Fields;
                  Fields = Lines[0].Split(new char[] { ',' });
                  int Cols = Fields.GetLength(0);
                  DataTable dt = new DataTable();
                  //1st row must be column names; force lower case to ensure matching later on.
                  for (int i = 0; i < Cols; i++)
                      dt.Columns.Add(Fields[i].ToUpper(), typeof(string));
                  DataRow Row;
                  for (int i = 1; i < Lines.GetLength(0)-1; i++)
                  {
                      Fields = Lines[i].Split(new char[] { ',' });
                      Row = dt.NewRow();
                      for (int f = 0; f < Cols; f++)
                      {
                          Row[f] = Fields[f];
                      }
                      dt.Rows.Add(Row);
                  }
                  return dt;
                  
              }
      

      ================================================ ==========================================

      方法二

      public DataTable DataGridtoDataTable(DataGrid dg)
              {
      
                  DataTable dt = new DataTable();
      
                  for (int i = 0; i <= dg.Columns.Count - 1; i++)
                  {
                      dt.Columns.Add(dg.Columns[i].Header.ToString(), typeof(string));
                  }
                  DataRow Row;
      
                  for (int i = 0; i <= dg.Items.Count - 1; i++)
                  {
                      Row = dt.NewRow();
      
                      for (int k = 0; k <= dg.Columns.Count - 1; k++)
                      {
                          Row[dg.Columns[k].Header.ToString()] = gettabelcell(i, k,dg);
      
                      }
                      dt.Rows.Add(Row);
                  }
      
                  return dt;
      
              }
      
      public String gettabelcell(int x, int y,DataGrid dg)
              {
                  try
                  {
                      String myString = dg.GetCell(x, y).ToString();
      
                      if (myString.Contains(":"))
                      {
                          String[] s = myString.Split(':');
                          String item = s[1];
                          return item.Trim();
                      }
                      else
                      {
                          return "";
                      }
                  }
                  catch
                  {
                      return "";
                  }
              }
      

      这是课

      static class ExtensionHelpers
         {
      
             public 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;
             }
      
             public static DataGridCell GetCell(this DataGrid grid, int row, int column)
             {
                 DataGridRow rowContainer = grid.GetRow(row);
                 return grid.GetCell(rowContainer, column);
             }
             public static DataGridRow GetSelectedRow(this DataGrid grid)
             {
                 return (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem);
             }
             public static DataGridRow GetRow(this DataGrid grid, int index)
             {
                 DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
                 if (row == null)
                 {
                     // May be virtualized, bring into view and try again.
                     grid.UpdateLayout();
                     grid.ScrollIntoView(grid.Items[index]);
                     row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
                 }
                 return row;
             }
      
             public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column)
             {
                 if (row != null)
                 {
                     DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
      
                     if (presenter == null)
                     {
                         grid.ScrollIntoView(row, grid.Columns[column]);
                         presenter = GetVisualChild<DataGridCellsPresenter>(row);
                     }
      
                     DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
                     return cell;
                 }
                 return null;
             }
         }
      

      【讨论】:

        【解决方案4】:

        你不能像在 winforms 中那样在 WPF 中做到这一点。在 Wpf 中,您可以像这样从 dataTable 设置 datagrid ItemsSource。

        dg.ItemsSource = dataTable.AsDataView();
        

        在您的情况下,您想从 datagrid 获取 dataTable。 所以你可以试试下面的代码。

        DataView view = (DataView) dg.ItemsSource;
        DataTable dataTable = view.Table.Clone();
        foreach (var dataRowView in view)
        {
            dataTable.ImportRow(dataRowView.Row);
        }
        var dataTableFromDataGrid = dataTable;
        

        【讨论】:

          猜你喜欢
          • 2014-03-16
          • 1970-01-01
          • 2011-10-22
          • 1970-01-01
          • 2013-03-17
          • 1970-01-01
          • 2011-08-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多