Convert DataGrid.ItemsSource to DataTable and transfer its values to DataTable without using Linq commands in WPF (by C#)

رضا جافری 1,296 Reputation points
2021-09-07T06:02:47.75+00:00

First and foremost, I apologize for my grammatical errors; my first language is Persian (Iran).
I use DataView RowFilter to filter the Datagrid row, I want to restore the previous Datagrid information if the user removes the filter.
So before applying the filter in DataGrid, I need its data.
I used the following method to convert DataGrid, this method converts datagrid to datatable but does not transfer its data in DataGrid:

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();
 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;    
}

This is my method:

PreviousMemberDT = MemberDT.Clone();
public DataTable Filter(DataTable dataTable,DataTable previousDataTable, string column, TextBox textBox, 
DataGrid dataGrid)
{
 previousDataTable = DataGridtoDataTable(dataGrid);
 OleDbCommand OleDCmd = new OleDbCommand("Select * From MemberTable", OleDbConnect);
 OleDCmd.CommandType = CommandType.Text;
 OleDbConnect.Open();
 OleDbDataAdapter DA;
 DA = new OleDbDataAdapter(OleDCmd);
 dataTable.Clear();
 DA.Fill(dataTable);
 DataView DV = new DataView(dataTable);
 DV.RowFilter = "[" + column + "]='" + textBox.Text.Trim() + "'";
 MemberDT = DV.ToTable();
 dataGrid.ItemsSource = MemberDT.DefaultView;
 OleDbConnect.Close();
 return previousDataTable;
}

I also tried the following code:

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

Thanks

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,603 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
789 questions
0 comments No comments
{count} votes

Accepted answer
  1. Hui Liu-MSFT 47,256 Reputation points Microsoft Vendor
    2021-09-07T09:37:11.13+00:00

    I'm not sure if the ItemsSource data of your DataGrid is a collection of objects or a DataTable.
    I used the collection as the ItemsSource of the DataGrid and converted its data to the DataTable through the following code. And by displaying the DataTable in another DataGrid to check whether the data is successfully converted. You could check it and try to refer to it in your project.
    The code of xaml:

    <StackPanel Orientation="Horizontal">  
            <DataGrid Name="dg" Width="300" AutoGenerateColumns="False">  
                <DataGrid.Columns>  
                    <DataGridTextColumn Header="Name" Binding="{Binding Name}" />  
                    <DataGridTextColumn Header="Birthday" Binding="{Binding Birthday}" />  
                </DataGrid.Columns>  
                <DataGrid.RowDetailsTemplate>  
                    <DataTemplate>  
                        <TextBlock Text="{Binding Details}" Margin="10" />  
                    </DataTemplate>  
                </DataGrid.RowDetailsTemplate>  
            </DataGrid>  
            <Button Content="convert " Height="50" Click="Button_Click_1" />  
            <DataGrid x:Name="dg2" Width="400"  >  
                  
            </DataGrid>  
    </StackPanel>  
    

    The code of xaml.cs:

    using System;  
    using System.Collections.Generic;  
    using System.Data;  
    using System.Reflection;  
    using System.Windows;  
    namespace DataGridToDataTable  
    {  
      public partial class MainWindow : Window  
      {  
        DataTable myDataTable;  
        public MainWindow()  
        {  
          InitializeComponent();  
             List<User> users = new List<User>();  
             users.Add(new User() { Id = 1, Name = "John Doe", Birthday = new DateTime(1971, 7, 23) });  
             users.Add(new User() { Id = 2, Name = "Jane Doe", Birthday = new DateTime(1974, 1, 17) });  
             users.Add(new User() { Id = 3, Name = "Sammy Doe", Birthday = new DateTime(1991, 9, 2) });  
             dg.ItemsSource = users;  
           }  
        private void Button_Click_1(object sender, RoutedEventArgs e)  
        {  
          var list = new List<User>(dg.ItemsSource as IEnumerable<User>);  
          myDataTable = ToDataTable(list);  
          if (myDataTable != null)  
          {  
          }  
          dg2.ItemsSource = myDataTable.DefaultView;  
        }  
        public static DataTable ToDataTable<T>(List<T> items)  
        {  
          DataTable dataTable = new DataTable(typeof(T).Name);  
          PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);  
          foreach (PropertyInfo prop in Props)  
          {  
            dataTable.Columns.Add(prop.Name);  
          }  
          foreach (T item in items)  
          {  
            var values = new object[Props.Length];  
            for (int i = 0; i < Props.Length; i++)  
            {  
              values[i] = Props[i].GetValue(item, null);  
            }  
            dataTable.Rows.Add(values);  
          }  
          return dataTable;  
        }  
      }  
      public class User  
      {  
           public int Id { get; set; }  
           public string Name { get; set; }  
           public DateTime Birthday { get; set; }  
           public string Details  
           {  
             get  
             {  
                  return String.Format("{0} was born on {1} and this is a long description of the person.", this.Name, this.Birthday.ToLongDateString());  
             }  
           }  
      }  
    }  
    

    The picture of result:

    129790-1.gif


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful