Search code examples
c#mysqlwpfdatagridrtf

How to retrieve RichText content From (MySQL) table to a WPF RichTextBox


I have an application where I have to store (and retrieve) supplier data from and into my WPF page, one of the fields is a RichTextBox

On my Xaml page I defined the Rich text block like this

<TabItem Header="Memo">
    <Grid Background="#FFE5E5E5">
       <TextBlock   Text="Comments" HorizontalAlignment="Left" VerticalAlignment="Top" 
                    Margin="10,10" FontWeight="Bold" Foreground="DarkRed"/>
       <RichTextBox x:Name="inpSupplierMemo" HorizontalAlignment="Center" 
                    VerticalAlignment="Top" Margin="10,70,10,0" Height="182" Width="Auto">
                    <FlowDocument>
                        <Paragraph>
                            <Run Text=""/>
                        </Paragraph>
                    </FlowDocument>
        </RichTextBox>
    </Grid>
</TabItem>

In my MySql Database table I defined the field as LONGTEXT

enter image description here

My C# Code to store the rich text data into the field:

private void ToolbarButtonSave(object sender, RoutedEventArgs e)
{
    string ContentSupplierMemo;

    if (inpSupplierCode.Text != "")
    {
        TextRange tr = new(inpSupplierMemo.Document.ContentStart, 
        inpSupplierMemo.Document.ContentEnd);
        using (MemoryStream ms = new())
        {
            tr.Save(ms, DataFormats.Rtf);
            ContentSupplierMemo = Encoding.ASCII.GetString(ms.ToArray());
        }
    }
    else { ContentSupplierMemo = ""; }

    Database dbConnection = new Database
    {
        TableName = DatabaseTable
    };

    dbConnection.Connect();
    dbConnection.SqlCommand = "UPDATE ";
    dbConnection.SqlCommandString = " SET " +
    "supplier_Code = '" + inpSupplierCode.Text + "', " +
    "supplier_Name = '" + inpSupplierName.Text + "', " +
    "supplier_Address1 = '" + inpSupplierAddress1.Text + "', " +
    "supplier_Address2 = '" + inpSupplierAddress2.Text + "', " +
    "supplier_Zip = '" + inpSupplierZip.Text + "', " +
    "supplier_City = '" + inpSupplierCity.Text + "', " +
    "supplier_Url = '" + inpSupplierUrl.Text + "', " +
    "supplier_Memo = '" + ContentSupplierMemo + "', " +
    "supplier_Id = " + valueSupplierId.Text + ";";

    dbConnection.TableName = DatabaseTable;

    _ = dbConnection.UpdateMySqlDataRecord();
    DataTable dtSupplierCodes = dbConnection.LoadMySqlData();

    // Load the data from the database into the datagrid
    SupplierCode_DataGrid.DataContext = dtSupplierCodes;

    // Make sure the eddited row in the datagrid is selected
    SupplierCode_DataGrid.SelectedIndex = int.Parse(valueSupplierId.Text) - 1;
    SupplierCode_DataGrid.Focus();
}

For so far Showing the RichTextBox and saving the data. If I run the application I am able to enter text and save it (Save button not shown in the screenshot)

enter image description here

The content of the richtext box is stored in the database

enter image description here

And content in detail

enter image description here

So far so good But when I retrieve the content from the database I am not able to show the original content anymore.

My C# code for data retrieval:

private void SupplierCode_DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    DataGrid dataGrid = (DataGrid)sender;

    if (dataGrid.SelectedItem is not DataRowView Row_Selected)
    {
        return;
    }

    valueSupplierId.Text = Row_Selected["supplier_Id"].ToString();
    inpSupplierCode.Text = Row_Selected["supplier_Code"].ToString();
    inpSupplierName.Text = Row_Selected["supplier_Name"].ToString();
    inpSupplierAddress1.Text = Row_Selected["supplier_Address1"].ToString();
    inpSupplierAddress2.Text = Row_Selected["supplier_Address2"].ToString();
    inpSupplierZip.Text = Row_Selected["supplier_Zip"].ToString();
    inpSupplierCity.Text = Row_Selected["supplier_City"].ToString();
    inpSupplierUrl.Text = Row_Selected["supplier_Url"].ToString();
    inpSupplierMemo.Document.Blocks.Clear();

    // Read formatted ritch text from table and store in field
    string ContentSupplierMemo = Row_Selected["supplier_Memo"].ToString();

    if (ContentSupplierMemo != "")
    {
        byte[] byteArray = Encoding.ASCII.GetBytes(ContentSupplierMemo);
        using (MemoryStream ms = new(byteArray))
        {
            TextRange tr = new(inpSupplierMemo.Document.ContentStart, inpSupplierMemo.Document.ContentEnd);
            tr.Load(ms, DataFormats.Rtf);
        }
    }
}

And the result of this code is:

enter image description here

But I expected

enter image description here

Where do I go wrong, can someone help me with this.

I googled for three days now and only see more or less the same solution, tried different ones, but with this solution I come closest to my goal, but not there yet.

Regards, Herbert


Solution

  • Below is a demo project that shows how to store data from a TextBlock in a database. It also shows how to retrieve the data from the database and display it in a TextBlock.

    The following code has been tested. longtext is used for supplier_Memo. Alternatively, one could use longblob (or mediumblob, if it meets your needs). Since longblob is binary data, the code below would need to be modified to pass data as byte[] instead of string.

    It's also important to use parameters to avoid SQL injection.


    Create a new WPF App (.NET Framework) project (name: DatabaseMySqlHN)

    VS 2019:

    MainWindow.xaml

    <Window x:Class="DatabaseMySqlHN.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:DatabaseMySqlHN"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="40" />
                <RowDefinition Height="25" />
                <RowDefinition Height="150" />
                <RowDefinition Height="25" />
                <RowDefinition Height="*" />
                <RowDefinition Height="20" />
            </Grid.RowDefinitions>
    
            <Grid Grid.Row="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="10" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="10" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="10" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="10" />
                </Grid.ColumnDefinitions>
    
                <Button Grid.Column="0" x:Name="btnCreateTbl" Click="btnCreateTbl_Click">Create Table</Button>
                <Button Grid.Column="2" x:Name="btnInsertTestData" Click="btnInsertTestData_Click">Insert Test Data</Button>
                <Button Grid.Column="4" x:Name="btnGetData" Click="btnGetData_Click">Get Data</Button>
                <Button Grid.Column="6" x:Name="btnSaveUpdate" Click="btnSaveUpdate_Click">Save/Update</Button>
            </Grid>
    
            <DataGrid Grid.Row="2" x:Name="SupplierCode_DataGrid" ItemsSource="{Binding}" SelectionChanged="SupplierCode_DataGrid_SelectionChanged"></DataGrid>
    
            <TabControl Grid.Row="4" x:Name="tabControl1">
                <TabItem Header="Memo">
                    <Grid Background="#FFE5E5E5">
                        <TextBlock   Text="Comments" HorizontalAlignment="Left" VerticalAlignment="Top" 
                        Margin="10,10" FontWeight="Bold" Foreground="DarkRed"/>
                        <RichTextBox x:Name="inpSupplierMemo" HorizontalAlignment="Center" 
                        VerticalAlignment="Top" Margin="10,70,10,0" Height="182" Width="Auto">
                            <FlowDocument Name="inpSupplierMemoFD">
                                <Paragraph>
                                    <Run Text=""/>
                                </Paragraph>
                            </FlowDocument>
                        </RichTextBox>
                    </Grid>
                </TabItem>
            </TabControl>
    
            <TextBox Grid.Row="5" Name="textBoxStatus" IsReadOnly="True" Text="" Background="LightGray"></TextBox>
        </Grid>
    </Window>
    

    Database table: Supplier

    Note: In the code below, I've tried to maintain the database column names that were supplied in the OP. However, the table name really shouldn't be part of the column names.

    Instead of naming the column supplier_Code, name the column Code.

    Columns may need to be added/modified per your requirements.

    CREATE TABLE Supplier (supplier_Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
                                                               supplier_Code varchar(4),
                                                               supplier_Name varchar(80),    
                                                               supplier_Address1 varchar(80),
                                                               supplier_Address2 varchar(80),
                                                               supplier_Zip varchar(80),
                                                               supplier_City varchar(80),
                                                               supplier_Url varchar(80),
                                                               supplier_MailSales varchar(80),
                                                               supplier_MailSupport varchar(80),
                                                               supplier_Memo longtext,
                                                               currency_Id int,
                                                               currency_Code varchar(4));
    

    enter image description here

    Create a class (name: HelperMySql.cs)

    HelperMySql.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using MySql.Data;
    using MySql.Data.MySqlClient;
    using System.Data;
    using System.Diagnostics;
    
    namespace DatabaseMySqlHN
    {
        public class HelperMySQL
        {
            public string ConnectionStr { get; set; } = string.Empty;
    
            public HelperMySQL(string serverName, string databaseName, string username, string userPwd)
            {
                ConnectionStr = String.Format("Server={0};Database={1};Uid={2};Pwd={3};", serverName, databaseName, username, userPwd);
            }
    
            public HelperMySQL(string serverName, int portNumber, string databaseName, string username, string userPwd)
            {
                ConnectionStr = String.Format("Server={0};Port={1};Database={2};Uid={3};Pwd={4};", serverName, portNumber, databaseName, username, userPwd);
            }
    
            public string CreateTableSupplier()
            {
                string msg = string.Empty;
    
                try
                {
                    //for mySQL, use backticks if tablename has space in it
                    //total max size for all columns is 65535 - excluding TEXT and BLOB
                    string sqlText = @"CREATE TABLE Supplier (supplier_Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
                                                               supplier_Code varchar(4),
                                                               supplier_Name varchar(80),    
                                                               supplier_Address1 varchar(80),
                                                               supplier_Address2 varchar(80),
                                                               supplier_Zip varchar(80),
                                                               supplier_City varchar(80),
                                                               supplier_Url varchar(80),
                                                               supplier_MailSales varchar(80),
                                                               supplier_MailSupport varchar(80),
                                                               supplier_Memo longtext,
                                                               currency_Id int,
                                                               currency_Code varchar(4));";
    
                    ExecuteNonQuery(sqlText);
    
                    Debug.WriteLine("Info: Table created (Supplier)");
                    msg = "Status: Table created (Supplier).";
                    
                }
                catch (MySqlException ex)
                {
                    msg = "Error: (CreateTableSupplier - MySqlException) - " + ex.Message;
                    Debug.WriteLine(msg);
                    //throw ex;
                }
                catch (Exception ex)
                {
                    msg = "Error: (CreateTableSupplier) - " + ex.Message;
                    Debug.WriteLine(msg);
                    //throw ex;
                }
    
                return msg;
            }
    
            public void ExecuteNonQuery(string sqlText)
            {
                using (MySqlConnection con = new MySqlConnection(ConnectionStr))
                {
                    //open
                    con.Open();
    
                    using (MySqlCommand cmd = new MySqlCommand(sqlText, con))
                    {
                        //execute
                        cmd.ExecuteNonQuery();
                    }
                }
            }
    
            public int ExecuteNonQueryTblSupplier(string sqlText, string supplierCode, string supplierName, string supplierAddress1, string supplierAddress2, string supplierZip, string supplierCity, string supplierUrl, string supplierMemo, int supplierId = 0)
            {
                int rowsAffected = 0;
    
                using (MySqlConnection con = new MySqlConnection(ConnectionStr))
                {
                    //open
                    con.Open();
    
                    using (MySqlCommand cmd = new MySqlCommand(sqlText, con))
                    {
    
                        //set values - if they exist
                        //if a value is null, one must use DBNull.Value
                        //if the value is DBNull.Value, and the table column doesn't allow nulls, this will cause an error
    
                        //add parameters setting string values to DBNull.Value
                        cmd.Parameters.Add("@supplierId", MySqlDbType.Int32).Value = supplierId;
                        cmd.Parameters.Add("@supplierCode", MySqlDbType.VarChar).Value = DBNull.Value;
                        cmd.Parameters.Add("@supplierName", MySqlDbType.VarChar).Value = DBNull.Value;
                        cmd.Parameters.Add("@supplierAddress1", MySqlDbType.VarChar).Value = DBNull.Value;
                        cmd.Parameters.Add("@supplierAddress2", MySqlDbType.VarChar).Value = DBNull.Value;
                        cmd.Parameters.Add("@supplierZip", MySqlDbType.VarChar).Value = DBNull.Value;
                        cmd.Parameters.Add("@supplierCity", MySqlDbType.VarChar).Value = DBNull.Value;
                        cmd.Parameters.Add("@supplierUrl", MySqlDbType.VarChar).Value = DBNull.Value;
                        cmd.Parameters.Add("@supplierMemo", MySqlDbType.LongText).Value = DBNull.Value;
    
                        //set values
                        if (!String.IsNullOrEmpty(supplierCode))
                            cmd.Parameters["@supplierCode"].Value = supplierCode;
    
                        if (!String.IsNullOrEmpty(supplierName))
                            cmd.Parameters["@supplierName"].Value = supplierName;
    
                        if (!String.IsNullOrEmpty(supplierAddress1))
                            cmd.Parameters["@supplierAddress1"].Value = supplierAddress1;
    
                        if (!String.IsNullOrEmpty(supplierAddress2))
                            cmd.Parameters["@supplierAddress2"].Value = supplierAddress2;
    
                        if (!String.IsNullOrEmpty(supplierZip))
                            cmd.Parameters["@supplierZip"].Value = supplierZip;
    
                        if (!String.IsNullOrEmpty(supplierCity))
                            cmd.Parameters["@supplierCity"].Value = supplierCity;
    
                        if (!String.IsNullOrEmpty(supplierUrl))
                            cmd.Parameters["@supplierUrl"].Value = supplierUrl;
    
                        if (supplierMemo != null && supplierMemo.Length > 0)
                            cmd.Parameters["@supplierMemo"].Value = supplierMemo;
    
                        //execute; returns the number of rows affected
                        rowsAffected = cmd.ExecuteNonQuery();
                    }
                }
    
                return rowsAffected;
            }
    
            public DataTable GetDataTblSupplier(int supplierId = 0)
            {
                DataTable dt = new DataTable();
                string sqlText = string.Empty;
    
                if (supplierId > 0)
                {
                    sqlText = "SELECT * from Supplier where supplier_Id = @supplierId";
                }
                else
                {
                    sqlText = "SELECT * from Supplier";
                }
    
                using (MySqlConnection con = new MySqlConnection(ConnectionStr))
                {
                    //open
                    con.Open();
    
                    using (MySqlCommand cmd = new MySqlCommand(sqlText, con))
                    {
                        //add parameter
                        cmd.Parameters.Add("@supplierId", MySqlDbType.Int32).Value = supplierId;
    
                        using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
                        {
                            //use DataAdapter to fill DataTable
                            da.Fill(dt);
                        }
                    }
                }
    
                return dt;
            }
    
            public string InsertTblSupplier(string supplierCode, string supplierName, string supplierAddress1, string supplierAddress2, string supplierZip, string supplierCity, string supplierUrl, string supplierMemo)
            {
                string result = string.Empty;
                string sqlText = "INSERT INTO Supplier  (supplier_Code, supplier_Name, supplier_Address1, supplier_Address2, supplier_Zip, supplier_City, supplier_Url, supplier_Memo) VALUES (@supplierCode, @supplierName, @supplierAddress1, @supplierAddress2, @supplierZip, @supplierCity, @supplierUrl, @supplierMemo);";
    
                try
                {
                    int rowsAffected = ExecuteNonQueryTblSupplier(sqlText, supplierCode, supplierName, supplierAddress1, supplierAddress2, supplierZip, supplierCity, supplierUrl, supplierMemo);
    
                    if (rowsAffected > 0)
                    {
    
                        result = String.Format("Row added.");
                    }
                    else
                    {
                        result = "Row not added.";
                    }
                }
                catch (MySqlException ex)
                {
                    Debug.WriteLine("Error (UpdateTblSupplier - MySqlException): " + ex.Message);
                    throw ex;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Error (UpdateTblSupplier): " + ex.Message);
                    throw ex;
                }
    
                return result;
            }
    
            public string UpdateTblSupplier(int supplierId, string supplierCode, string supplierName, string supplierAddress1, string supplierAddress2, string supplierZip, string supplierCity, string supplierUrl, string supplierMemo)
            {
                string result = string.Empty;
                string sqlText = "UPDATE Supplier SET supplier_Code = @supplierCode, supplier_name = @supplierName, supplier_Address1 = @supplierAddress1, supplier_Address2 = @supplierAddress2, supplier_Zip = @supplierZip, supplier_City = @supplierCity, supplier_Url = @supplierUrl, supplier_Memo = @supplierMemo WHERE supplier_Id = @supplierId;";
    
                try
                {
                    int rowsAffected = ExecuteNonQueryTblSupplier(sqlText, supplierCode, supplierName, supplierAddress1, supplierAddress2, supplierZip, supplierCity, supplierUrl, supplierMemo, supplierId);
    
                    if (rowsAffected > 0)
                    {
                        result = "Updated successfully";
                    }
                    else
                    {
                        result = "No rows were updated.";
                    }
                }
                catch (MySqlException ex)
                {
                    Debug.WriteLine("Error (UpdateTblSupplier - MySqlException): " + ex.Message);
                    throw ex;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Error (UpdateTblSupplier): " + ex.Message);
                    throw ex;
                }
    
                return result;
            }
        }
    }
    

    MainWindow.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Diagnostics;
    using System.Data;
    using System.IO;
    
    namespace DatabaseMySqlHN
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            private HelperMySQL _helper = null;
            private System.Data.DataTable _dt = null;
            private int _currentDataGridIndex = 0;
            private int _dbRowCount = 0;
    
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void GetData()
            {
                InitializeHelper();
    
                //get data from database
                _dt = _helper.GetDataTblSupplier();
    
                //populate data in DataGrid from DataTable
                SupplierCode_DataGrid.DataContext = _dt;
    
                //set value
                _dbRowCount = _dt.Rows.Count;
    
                //clear existing data
                inpSupplierMemo.Document.Blocks.Clear();
            }
    
            private void GetMemo(int index)
            {
                string ContentSupplierMemo = string.Empty;
    
                if (_dt != null && index >= 0 && index < _dt.Rows.Count)
                {
                    //set value
                    DataRow row = _dt.Rows[index];
    
    
                    if (row["supplier_Memo"] != null && row["supplier_Memo"] != DBNull.Value)
                    {
                        //get value from DataTable
                        ContentSupplierMemo = row["supplier_Memo"].ToString();
                    }
                
                    if (!String.IsNullOrEmpty(ContentSupplierMemo))
                    {
                        //Debug.WriteLine("Length: " + ContentSupplierMemo.Length);
    
                        //clear existing data
                        inpSupplierMemo.Document.Blocks.Clear();
    
                        //convert to byte[]
                        byte[] dataArr = System.Text.Encoding.UTF8.GetBytes(ContentSupplierMemo);
    
                        using (MemoryStream ms = new MemoryStream(dataArr))
                        {
                            //inpSupplierMemo.Document = new FlowDocument();
    
                            //load data
                            TextRange flowDocRange = new TextRange(inpSupplierMemo.Document.ContentStart, inpSupplierMemo.Document.ContentEnd);
                            flowDocRange.Load(ms, DataFormats.Rtf);
                        }
                    }
                }
            }
    
            private string GetRichTextFromFlowDocument(FlowDocument fDoc)
            {
                string result = string.Empty;
    
                //convert to string
                if (fDoc != null)
                {
                    TextRange tr = new TextRange(fDoc.ContentStart, fDoc.ContentEnd);
    
                    using (MemoryStream ms = new MemoryStream())
                    {
                        tr.Save(ms, DataFormats.Rtf);
                        result = System.Text.Encoding.UTF8.GetString(ms.ToArray());
                    }
                }
    
                return result;
            }
    
            private void InitializeHelper()
            {
                if (_helper == null)
                {
                    //servername, databaseName, userName, userPassword
                    _helper = new HelperMySQL("localhost", "HN", "testUser", "removed");
                }
            }
    
            private void InsertRow(int dgIndex)
            {
                //since the DataGrid DataContext is set to the DataTable, 
                //the DataTable is updated when data is modified in the DataGrid
                //get last row
                DataRow row = _dt.Rows[_dt.Rows.Count - 1];
    
                //get data from DataTable
                string supplierCode = row["supplier_Code"].ToString();
                string supplierName = row["supplier_Name"].ToString();
                string supplierAddress1 = row["supplier_Address1"].ToString();
                string supplierAddress2 = row["supplier_Address2"].ToString();
                string supplier_Zip = row["supplier_Zip"].ToString();
                string supplier_City = row["supplier_City"].ToString();
                string supplier_Url = row["supplier_Url"].ToString();
    
                //convert RTF to string
                string memo = GetRichTextFromFlowDocument(inpSupplierMemo.Document);
    
                InitializeHelper();
    
                string result = string.Empty;
                result = _helper.InsertTblSupplier(supplierCode, supplierName, supplierAddress1, supplierAddress2, supplier_Zip, supplier_City, supplier_Url, memo);
                UpdateStatus(result);
            }
    
            private void UpdateRow(int dgIndex)
            {
                //when DataGrid SelectionChanged occurs, the value of '_currentDataGridIndex' is set
                //to DataGrid SelectedIndex
                //get data from DataTable
                DataRow row = _dt.Rows[_currentDataGridIndex];
    
                int supplierId = (int)row["supplier_Id"];
                string supplierCode = row["supplier_Code"].ToString();
                string supplierName = row["supplier_Name"].ToString();
                string supplierAddress1 = row["supplier_Address1"].ToString();
                string supplierAddress2 = row["supplier_Address2"].ToString();
                string supplier_Zip = row["supplier_Zip"].ToString();
                string supplier_City = row["supplier_City"].ToString();
                string supplier_Url = row["supplier_Url"].ToString();
    
                //convert RTF to string
                string memo = GetRichTextFromFlowDocument(inpSupplierMemo.Document);
    
                InitializeHelper();
    
                string result = string.Empty;
                result = _helper.UpdateTblSupplier(supplierId, supplierCode, supplierName, supplierAddress1, supplierAddress2, supplier_Zip, supplier_City, supplier_Url, memo);
                UpdateStatus(result);
            }
    
            private void UpdateStatus(string msg)
            {
                if (!String.IsNullOrEmpty(msg))
                {
                    if (!msg.StartsWith("Error") && !msg.StartsWith("Status"))
                    {
                        textBoxStatus.Text = String.Format("Status: {0} ({1})", msg, DateTime.Now.ToString("HH:mm:ss"));
                        Debug.WriteLine(String.Format("{0} - Status: {1}", DateTime.Now.ToString("HH:mm:ss"), msg));
                    }
                    else
                    {
                        textBoxStatus.Text = String.Format("{0} ({1})", msg, DateTime.Now.ToString("HH:mm:ss"));
                        Debug.WriteLine(String.Format("{0} - {1}", DateTime.Now.ToString("HH:mm:ss"), msg));
                    }
                }
            }
    
            private void btnCreateTbl_Click(object sender, RoutedEventArgs e)
            {
                InitializeHelper();
    
                //create table
                string result = _helper.CreateTableSupplier();
                UpdateStatus(result);
            }
    
            private void btnGetData_Click(object sender, RoutedEventArgs e)
            {
                GetData();
    
                //update status
                string msg = "Status: '" + _dt.Rows.Count + "' rows retrieved.";
                UpdateStatus(msg);
            }
    
            private void SupplierCode_DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                DataGrid dg = (DataGrid)sender;
    
                //set value
                _currentDataGridIndex = dg.SelectedIndex;
    
                GetMemo(dg.SelectedIndex);
            }
    
    
            private void btnSaveUpdate_Click(object sender, RoutedEventArgs e)
            {
                int rowIndex = _currentDataGridIndex;
    
                if (_dt.Rows.Count >  _dbRowCount)
                {
                    InsertRow(SupplierCode_DataGrid.SelectedIndex);
                }
                else
                {
                    UpdateRow(SupplierCode_DataGrid.SelectedIndex);
                }
    
                GetData();
    
                // Make sure the eddited row in the datagrid is selected
                SupplierCode_DataGrid.SelectedIndex = rowIndex;
                SupplierCode_DataGrid.Focus();
            }
    
            private void btnInsertTestData_Click(object sender, RoutedEventArgs e)
            {
                string result = string.Empty;
    
                GetData();
    
                //only insert test data if no rows exist
                if (_dt.Rows.Count == 0)
                {
                    string memo1 = @"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
    {\*\generator Riched20 10.0.19041}\viewkind4\uc1 
    \pard\sa200\sl276\slmult1\f0\fs22\lang9 Test Comments 1\par
    }";
    
                    string memo2 = @"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
    {\*\generator Riched20 10.0.19041}\viewkind4\uc1 
    \pard\sa200\sl276\slmult1\f0\fs22\lang9 Test Comments 2\par
    }";
    
                    InitializeHelper();
    
                    result = _helper.InsertTblSupplier("1", "Acme 123", "51 my street", null, "12345", "Some City", "https://www.myUrl1.com", memo1);
                    UpdateStatus(result);
    
                    result = _helper.InsertTblSupplier("2", "Acme 456", "52 my street", null, "12345", "Some City", "https://www.myUrl2.com", memo2);
                    UpdateStatus(result);
    
                    GetData();
                }
                else
                {
                    UpdateStatus("Status: Data exists in table-test data not added.");
                }
            }
        }
    }
    

    enter image description here

    Resources: