Click here to Skip to main content
15,881,687 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
First and foremost, I apologize for my grammatical errors; my first language is Persian (Iran).
I have a DataGrid that has 18 columns (column index starts from 0 to 17):
See this image
I need the DataTable return type, so I tried the following code and methods:

What I have tried:

DataTable BookDT = new DataTable();
public MainWindow()
{
    InitializeComponent();
    BookDT.Columns.Clear();
    BookDT.Columns.Add("BookName", typeof(string));
    BookDT.Columns.Add("Publisher", typeof(string));
    BookDT.Columns.Add("Category", typeof(string));
    BookDT.Columns.Add("BookCode", typeof(string));
    BookDT.Columns.Add("Inventory", typeof(string));
    BookDT.Columns.Add("DateTaken", typeof(string));
    BookDT.Columns.Add("RecipientName", typeof(string));
    BookDT.Columns.Add("ReturnDate", typeof(string));
    BookDT.Columns.Add("ReleaseDate", typeof(string));
    BookDT.Columns.Add("BookLanguage", typeof(string));
    BookDT.Columns.Add("Length", typeof(string));
    BookDT.Columns.Add("Form", typeof(string));
    BookDT.Columns.Add("Translator", typeof(string));
    BookDT.Columns.Add("Narrator", typeof(string));
    BookDT.Columns.Add("ISBN", typeof(string));
    BookDT.Columns.Add("Location", typeof(string));
    BookDT.Columns.Add("Price", typeof(string));
    BookDT.Columns.Add("BookImage", typeof(byte[]));
}
public BitmapImage ConvertWriteableBitmapToBitmapImage(WriteableBitmap wbm)
{
    BitmapImage bmImage = new BitmapImage();
    using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
    {
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(wbm));
        encoder.Save(stream);
        bmImage.BeginInit();
        bmImage.CacheOption = BitmapCacheOption.OnLoad;
        bmImage.StreamSource = stream;
        bmImage.EndInit();
        bmImage.Freeze();
    }
    return bmImage;
}
public DataTable DataGridToDataTable(DataGrid DG, DataTable DT, byte NumberOfColumns, byte VisualColumnIndex)
{
    for (int i = 0; i < DG.SelectedItems.Count - 1; i++)
    {
        for (byte j = 0; j < NumberOfColumns; j++)
        {
            DT.Rows.Add(DG.SelectedItems[i]);
            switch (j == VisualColumnIndex)
            {
                case true:
                    Image TempImage = new Image() { Source = (VisualTreeHelper.GetChild(DG.Columns[j].GetCellContent(DG.SelectedItems[i]), 0) as Image).Source };
                    DT.Rows[i][j] = ImageToBytes(ConvertWriteableBitmapToBitmapImage(new WriteableBitmap((BitmapSource)TempImage.Source)));
                    break;
                default:
                    DT.Rows[i][j] = (((DG.Columns[j].GetCellContent((DataGridRow)DG.ItemContainerGenerator.ContainerFromIndex(i))) as TextBlock).Text).ToString();
                    break;
            }
        }
    }
    return DT;
}

And I use it as follows:
BookDT = DataGridToDataTable(BookDataGrid, BookDT, 18, 17);

I use the following method to bind:
See this image
XAML:
<Window.Resources>
    <local:DatabaseDataSet x:Key="Database_DataSet"/>
    <CollectionViewSource x:Key="BookTableViewSource" Source="{Binding BookTable, Source={StaticResource Database_DataSet}}"/>
    <CollectionViewSource x:Key="MemberTableViewSource" Source="{Binding MemberTable, Source={StaticResource Database_DataSet}}"/>
</Window.Resources>
<DataGrid x:Name="BookDataGrid" ContextMenu="{StaticResource DataGridContextMenu}" HeadersVisibility="Column" EnableRowVirtualization="True" AutoGenerateColumns="False" ItemsSource="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="486" Height="386" Margin="0">
             <DataGrid.Columns>
                 <DataGridTextColumn x:Name="BookName" Binding="{Binding BookName}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="Publisher" Binding="{Binding Publisher}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="Category" Binding="{Binding Category}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="BookCode" Binding="{Binding BookCode}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="Inventory" Binding="{Binding Inventory}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="DateTaken" Binding="{Binding DateTaken}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="RecipientName" Binding="{Binding RecipientName}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="ReturnDate" Binding="{Binding ReturnDate}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="ReleaseDate" Binding="{Binding ReleaseDate}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="Language" Binding="{Binding BookLanguage}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="Length" Binding="{Binding Length}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="Form" Binding="{Binding Form}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="Translator" Binding="{Binding Translator}" Width="SizeToHeader"/>
                 <DataGridTextColumn x:Name="Narrator" Binding="{Binding Narrator}"/>
                 <DataGridTextColumn x:Name="ISBN" Binding="{Binding ISBN}"/>
                 <DataGridTextColumn x:Name="Location" Binding="{Binding Location}"/>
                 <DataGridTextColumn x:Name="Price" Binding="{Binding Price}"/>
                 <DataGridTemplateColumn x:Name="BookImage" Width="SizeToHeader">
                     <DataGridTemplateColumn.CellTemplate>
                         <DataTemplate>
                             <Image Source="{Binding BookImage}"/>
                         </DataTemplate>
                     </DataGridTemplateColumn.CellTemplate>
                 </DataGridTemplateColumn>
             </DataGrid.Columns>
</DataGrid>

C#:
DatabaseDataSet Database_DataSet = ((DatabaseDataSet)TryFindResource("Database_DataSet"));
DatabaseDataSetTableAdapters.BookTableTableAdapter BookTable_TableAdapter = new DatabaseDataSetTableAdapters.BookTableTableAdapter();
BookTable_TableAdapter.Fill(Database_DataSet.BookTable);
CollectionViewSource BookTableViewSource = ((CollectionViewSource)TryFindResource("BookTableViewSource"));
BookTableViewSource.View.MoveCurrentToFirst();

I also asked this question in the following link:
Question
Thank you for your help
Posted
Updated 5-Apr-22 7:37am
v4

You already know what the type is, because you bound it to the grid. It's BookTable.

You'd be better off doing proper MVVM, as well as stop using CollectionViewSource. Bind the collection directly to the GridView.

You may be interested in a control I wrote that can automatically create the necessary columns in a ListView from the bound entity item. It'll save you a butt-load of manual coding. It supports sorting and cell formatting as well.

Auto-generated columns in a WPF ListView[^]
 
Share this answer
 
Comments
Reza jafery 28-Feb-22 14:20pm    
Hi, thank you for the feedback but I want to use DataGrid.
Reza jafery 28-Feb-22 14:23pm    
If you can answer this question accurately with the code and output, thank you.
Hello to all friends I found the solution.
You can see the output in this link
First of all, we need to set the DataGrid EnableRowVirtualization to False (this is best done in XAML), if this is not done, we will have a problem with the For loops.
We also need to choose a name for the Image control in the DataGridTemplateColumn column (in here Image name is "BookIMG").
So we have following XAML code for DataGrid:
XAML:
<DataGrid x:Name="BookDataGrid" ContextMenu="{StaticResource DataGridContextMenu}" HeadersVisibility="Column" EnableRowVirtualization="False" AutoGenerateColumns="False" ItemsSource="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="486" Height="386" Margin="0">
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="BookName" Binding="{Binding BookName}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="Publisher" Binding="{Binding Publisher}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="Category" Binding="{Binding Category}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="BookCode" Binding="{Binding BookCode}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="Inventory" Binding="{Binding Inventory}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="DateTaken" Binding="{Binding DateTaken}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="RecipientName" Binding="{Binding RecipientName}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="ReturnDate" Binding="{Binding ReturnDate}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="ReleaseDate" Binding="{Binding ReleaseDate}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="Language" Binding="{Binding BookLanguage}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="Length" Binding="{Binding Length}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="Form" Binding="{Binding Form}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="Translator" Binding="{Binding Translator}" Width="SizeToHeader"/>
        <DataGridTextColumn x:Name="Narrator" Binding="{Binding Narrator}"/>
        <DataGridTextColumn x:Name="ISBN" Binding="{Binding ISBN}"/>
        <DataGridTextColumn x:Name="Location" Binding="{Binding Location}"/>
        <DataGridTextColumn x:Name="Price" Binding="{Binding Price}"/>
        <DataGridTemplateColumn x:Name="BookImage" Width="SizeToHeader">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Image x:Name="BookIMG" Source="{Binding BookImage}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

Then we have to use the DataGridTemplateColumn.Cell.FindName method / property to get the image from the image column.
We also need the following method to convert the image control source to a byte array:
public byte[] ImageSourceToBytes(BitmapEncoder BitEncoder, ImageSource ImgSource)
{
    byte[] Bytes = null;
    switch ((ImgSource as BitmapSource) != null)
    {
        case true:
            BitEncoder.Frames.Add(BitmapFrame.Create((ImgSource as BitmapSource)));
            using (var Stream = new System.IO.MemoryStream())
            {
                BitEncoder.Save(Stream);
                Bytes = Stream.ToArray();
            }
            break;
    }
    return Bytes;
}

So based on the above description, I created the DataGridToDataTable method:
public DataTable DataGridToDataTable(DataGrid DG, DataTable DT, byte NumberOfColumns, byte VisualColumnIndex, string ControlName)
{
    for (int i = 0; i < DG.Items.Count - 1; i++)
    {
        DT.Rows.Add(DG.Items[i]);
    }
    for (int i = 0; i < DG.Items.Count - 1; i++)
    {
        for (byte j = 0; j < NumberOfColumns; j++)
        {
            switch (j == VisualColumnIndex)
            {
                case true:
                    DataGridRow Row = (DataGridRow)DG.ItemContainerGenerator.ContainerFromIndex(i);
                    FrameworkElement FE = DG.Columns[j].GetCellContent((Row));
                    Image Img = new Image() { Source = ((((DataGridTemplateColumn)DG.Columns[j]).CellTemplate.FindName(ControlName, FE) as Image).Source) };
                    DT.Rows[i][j] = ImageSourceToBytes(new PngBitmapEncoder(), Img.Source);
                    break;
                default:
                    Row = (DataGridRow)DG.ItemContainerGenerator.ContainerFromIndex(i);
                    DT.Rows[i][j] = ((DG.Columns[j].GetCellContent((Row))) as TextBlock).Text;
                    break;
            }
        }
    }
    return DT;
}

And I used it as follows:
BDT = DataGridToDataTable(BookDataGrid, BDT, 18, 17, "BookIMG");

Finally my code is as follows:
Note: I used additional code to display the output in PDF format (AddTitleAndPageNumberLTR and ExportLTR methods are used only to display the output of the program and you do not need them).
DataTable BDT = new DataTable();
void AddTitleAndPageNumberLTR(string FileIn, string FileOut, [Optional] string Date)
{
    byte[] Bytes = System.IO.File.ReadAllBytes(FileIn);
    PdfReader PDF_Reader = new PdfReader(Bytes);
    BaseFont BaseFont = BaseFont.CreateFont(System.Windows.Forms.Application.StartupPath + @"\Font Collection\Roboto.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
    iTextSharp.text.Font PageNumberFont = new iTextSharp.text.Font(BaseFont, 12);
    using (MemoryStream Stream = new MemoryStream())
    {
        iTextSharp.text.Rectangle PageSize = PDF_Reader.GetPageSize(1);
        using (PdfStamper Stamper = new PdfStamper(PDF_Reader, Stream))
        {
            PageNumberFont.Size = 9;
            ColumnText.ShowTextAligned(Stamper.GetUnderContent(1), iTextSharp.text.Element.ALIGN_CENTER, new iTextSharp.text.Phrase("Output"), ((PageSize.Left + PageSize.Right) / 2), PageSize.Top - 10, 0);
        }
        Bytes = Stream.ToArray();
    }
    System.IO.File.WriteAllBytes(FileOut, Bytes);
}
public void ExportLTR(DataTable dataTable,DataGrid dataGrid)
{
    iTextSharp.text.Document Doc = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 10f, 10f, 110f, 100f);
    PdfWriter PDF_Writer = PdfWriter.GetInstance(Doc, new FileStream((Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\Output.pdf"), FileMode.Create));
    Doc.Open();
    PDF_Writer.RunDirection = PdfWriter.RUN_DIRECTION_LTR;
    BaseFont Base_Font = BaseFont.CreateFont(System.Windows.Forms.Application.StartupPath + @"\Font Collection\Roboto.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
    iTextSharp.text.Font DT_Font = new iTextSharp.text.Font(Base_Font, 6);
    PdfPTable PDF_Table = new PdfPTable(dataTable.Columns.Count);
    PDF_Table.RunDirection = PdfWriter.RUN_DIRECTION_LTR;
    PDF_Table.WidthPercentage = 100;
    PdfPCell Cell = new PdfPCell();
    Cell.MinimumHeight = 20;
    for (byte i = 0; i < dataGrid.Columns.Count; i++)
    {
        PDF_Table.AddCell(new iTextSharp.text.Phrase(dataGrid.Columns[i].Header.ToString(), DT_Font));
    }
    for (int i = 0; i < BDT.Rows.Count; i++)
    {
        for (byte j = 0; j < BDT.Columns.Count; j++)
        {
            switch (j == 17)
            {
                case true:
                    PDF_Table.AddCell(iTextSharp.text.Image.GetInstance((byte[])BDT.Rows[i][j]));
                    break;
                default:
                    Cell.Phrase = new iTextSharp.text.Phrase(BDT.Rows[i][j].ToString(), DT_Font);
                    PDF_Table.AddCell(Cell);
                    break;
            }
        }
    }
    PDF_Table.SpacingBefore = 15;
    Doc.Add(PDF_Table);
    Doc.Close();
    AddTitleAndPageNumberLTR(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\Output.pdf", Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\Output.pdf");
}
public DataTable DataGridToDataTable(DataGrid DG, DataTable DT, byte NumberOfColumns, byte VisualColumnIndex, string ControlName)
{
    for (int i = 0; i < DG.Items.Count - 1; i++)
    {
        DT.Rows.Add(DG.Items[i]);
    }
    for (int i = 0; i < DG.Items.Count - 1; i++)
    {
        for (byte j = 0; j < NumberOfColumns; j++)
        {
            switch (j == VisualColumnIndex)
            {
                case true:
                    DataGridRow Row = (DataGridRow)DG.ItemContainerGenerator.ContainerFromIndex(i);
                    FrameworkElement FE = DG.Columns[j].GetCellContent((Row));
                    Image Img = new Image() { Source = ((((DataGridTemplateColumn)DG.Columns[j]).CellTemplate.FindName(ControlName, FE) as Image).Source) };
                    DT.Rows[i][j] = ImageSourceToBytes(new PngBitmapEncoder(), Img.Source);
                    break;
                default:
                    Row = (DataGridRow)DG.ItemContainerGenerator.ContainerFromIndex(i);
                    DT.Rows[i][j] = ((DG.Columns[j].GetCellContent((Row))) as TextBlock).Text;
                    break;
            }
        }
    }
    return DT;
}
private void Sync_Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    switch (BookDataGrid.Items.Count > 0)
    {
        case true:
            BDT.Columns.Clear();
            BDT.Columns.Add("BookName", typeof(string));
            BDT.Columns.Add("Publisher", typeof(string));
            BDT.Columns.Add("Category", typeof(string));
            BDT.Columns.Add("BookCode", typeof(long));
            BDT.Columns.Add("Inventory", typeof(string));
            BDT.Columns.Add("DateTaken", typeof(string));
            BDT.Columns.Add("RecipientName", typeof(string));
            BDT.Columns.Add("ReturnDate", typeof(string));
            BDT.Columns.Add("ReleaseDate", typeof(string));
            BDT.Columns.Add("BookLanguage", typeof(string));
            BDT.Columns.Add("Length", typeof(string));
            BDT.Columns.Add("Form", typeof(string));
            BDT.Columns.Add("Translator", typeof(string));
            BDT.Columns.Add("Narrator", typeof(string));
            BDT.Columns.Add("ISBN", typeof(string));
            BDT.Columns.Add("Location", typeof(string));
            BDT.Columns.Add("Price", typeof(string));
            BDT.Columns.Add("BookImage", typeof(byte[]));
            BDT = DataGridToDataTable(BookDataGrid, BDT, 18, 17, "BookIMG");
            ExportLTR(BDT,BookDataGrid);
            //The following code is not required
            OleDbConnect.Open();
            OleDbCommand OleDbCommand_Delete = new OleDbCommand("Delete * From [BookTable]", OleDbConnect);
            OleDbCommand_Delete.ExecuteNonQuery();
            OleDbCommand OleDbCommand_Insert = null;
            for (int i = 0; i < BookDataGrid.Items.Count-1; i++)
            {
                OleDbParameter Parameter = new OleDbParameter();
                Parameter.OleDbType = OleDbType.Binary;
                Parameter.ParameterName = "Image";
                Parameter.Value = BDT.Rows[i][17];
                OleDbCommand_Insert = new OleDbCommand("Insert Into [BookTable](BookName,Publisher,Category,BookCode,Inventory,DateTaken,RecipientName,ReturnDate,ReleaseDate,BookLanguage,Length,Form,Translator,Narrator,ISBN,Location,Price,BookImage)values('" + BDT.Rows[i][0].ToString() + "','" + BDT.Rows[i][1].ToString() + "','" + BDT.Rows[i][2].ToString() + "','" + long.Parse((BDT.Rows[i][3].ToString())) + "','" + BDT.Rows[i][4].ToString() + "','" + BDT.Rows[i][5].ToString() + "','" + BDT.Rows[i][6].ToString() + "','" + BDT.Rows[i][7].ToString() + "','" + BDT.Rows[i][8].ToString() + "','" + BDT.Rows[i][9].ToString() + "','" + BDT.Rows[i][10].ToString() + "','" + BDT.Rows[i][11].ToString() + "','" + BDT.Rows[i][12].ToString() + "','" + BDT.Rows[i][13].ToString() + "','" + BDT.Rows[i][14].ToString() + "','" + BDT.Rows[i][15].ToString() + "','" + BDT.Rows[i][16].ToString() + "',@Image)", OleDbConnect);
                OleDbCommand_Insert.Parameters.Add(Parameter);
                OleDbCommand_Insert.ExecuteScalar();
            }
            OleDbConnect.Close();
            break;
    }
}

Tested in:
Visual Studio 2017, .NET Framework 4.5.2, WPF
Thanks
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900