How do I replace text in a WPF richtextbox with values from datagrids

Hi,

I have a combobox populated with column names from three tables in a SQL server.

I also have three datagrids: customer, invoce and order

The combobox gets populated with these tables column names

I want to be able to select a column name in the combobox, for example CustomerName, click a button and insert CustomerName  wrapped with curly braces in a richtextbox.

If I have the text {CustomerName} in the richtextbox and click a button I want to replace {CustomerName} with selected customer's name in the customer datagrid.

Previously I had a static list in the combobox and I managed the replace with code below:

      ' to get the selected rowindexes in the datagrids
        Dim CustomerRowIndex As Integer
        CustomerRowIndex = dgCustomer.SelectedIndex

        Dim InvoiceRowIndex As Integer
        InvoiceRowIndex = dgInvoice.SelectedIndex

        Dim OrderRowIndex As Integer
        OrderRowIndex = dgOrders.SelectedIndex

'assign the selected row's columns to variables
Dim CustomerName As String = CustomerDataTableInstance.Rows(CustomerRowIndex).Item("CustomerName")
'and all the other values here

'Replace the text
Dim tr As New TextRange(rtbText.Document.ContentStart, rtbText.Document.ContentEnd)
        tr.Text = tr.Text.Replace("{CustomerName}", CustomerName)

The problem is, I don't know how to do it when I don't know what variables I will have. I need something that looks for { in the richtextbox and takes what's there before } and search for that column name in the datagrid and replaces it with selected row's value for that column.
msglAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

SiliconXPCommented:
 the code below should get you started

//using System;
//using System.Text.RegularExpressions;
//using System.Windows.Forms;
//using System.Text;

            string sourceText = "dear {CustomerName} your invoice {InvoiceNumber} of {invoiceDate} is due before you pick you order  number{OrderNumber";
            Regex theReg = new Regex(@"{(\w*?)}"
            	,  RegexOptions.IgnoreCase);
            MatchCollection theMatches = theReg.Matches(sourceText);
            foreach (Match theMatch in theMatches)
            {
            	StringBuilder sb = new StringBuilder();
            	
            		
            	if (theMatch.Length != 0)
                {
            		String tag=theMatch.ToString();
            		String fieldName=theMatch.Groups[1];
            		sb.AppendFormat("Replacement Tag in RichtextBox : {0}",tag).AppendLine();
                    sb.AppendFormat("FieldName: {0}",fieldName);

                   MessageBox.Show(sb.ToString());
                   
                   //you can do a case statement to take correct action for found tags
                   // i suggest you insert the tag formated as {InvoiceTable.InvoiceDate}
                   //this will help you know which table to get data from if two columns 
                   //are have same name but different table
                   
                   
                }
            }

Open in new window

0
msglAuthor Commented:
Hi SiliconXP,

Thank you for your answer. I converted the code to VB.NET and all my tables and columns starts with a three letter short form for each table/column so I always know which table to get data from.

Invoice table is names inv_invoice with fields like inv_id, inv_cus_id, inv_amount and table cus_customer with fields like cus_id, cus_name and so on. Order table is called ord_order with fields ord_id, ord_cus_id etc. With this I can use case statements and use StartsWIth("cus"), StartsWith("inv") and StartsWith("ord").

Some help to put it together or a bit more guidance would be very much appreciated.

Code:

Dim sourceText As String
        Dim input As New TextRange(rtbText.Document.ContentStart, rtbText.Document.ContentEnd)
        Dim pattern As String = "{(\w*?)}"

        sourceText = input.Text

        Dim CustomerRowIndex As Integer = dgCustomer.SelectedIndex
        Dim InvoiceRowIndex As Integer = dgInvoice.SelectedIndex
        Dim OrderRowIndex As Integer = dgOrders.SelectedIndex

        Dim matches As MatchCollection = Regex.Matches(sourceText, pattern)
        For Each match As Match In matches
            Dim sb As New StringBuilder()

            If match.Length <> 0 Then
                Dim tag As String = match.ToString()
                Dim fieldName As String = match.Groups(1).ToString
                sb.AppendFormat("Replacement Tag in RichtextBox : {0}", tag).AppendLine()
                sb.AppendFormat("FieldName: {0}", fieldName)

                Select Case fieldName
                    Case fieldName.StartsWith("Cus")
                        fieldName = Cus_CustomerDataTableInstance.Rows(CustomerRowIndex).Item(fieldName)
                    Case fieldName.StartsWith("Ord")
                        fieldName = Inv_InvoiceDataTableInstance.Rows(InvoiceRowIndex).Item(fieldName)
                    Case fieldName.StartsWith("Inv")
                        fieldName = Ord_OrderDataTableInstance.Rows(OrderRowIndex).Item(fieldName)
                End Select

            End If
        Next
    End Sub

0
SiliconXPCommented:
hi. try these changes
 Dim sourceText As String
        Dim input As New TextRange(rtbText.Document.ContentStart, rtbText.Document.ContentEnd)
        Dim pattern As String = "{(\w*?)}"

        sourceText = input.Text
        Dim targetText As StringBuilder = New StringBuilder(input.Text)

        Dim CustomerRowIndex As Integer = dgCustomer.SelectedIndex
        Dim InvoiceRowIndex As Integer = dgInvoice.SelectedIndex
        Dim OrderRowIndex As Integer = dgOrders.SelectedIndex

        Dim matches As MatchCollection = Regex.Matches(sourceText, pattern)
        For Each match As Match In matches
            Dim sb As New StringBuilder()

            If match.Length <> 0 Then
                Dim tag As String = match.ToString()
                Dim fieldName As String = match.Groups(1).ToString
                Dim fieldValue As String
                Dim tableName As String
                sb.AppendFormat("Replacement Tag in RichtextBox : {0}", tag).AppendLine()
                sb.AppendFormat("FieldName: {0}", fieldName)
                'check these lines to make sure they return correct infor.i didnt verify.
                tableName = fieldName.Substring(0, fieldName.IndexOf("_"))
                fieldName = fieldName.Substring(fieldName.IndexOf("_"))
                Select Case tableName
                    Case "Cus"
                        fieldValue = Cus_CustomerDataTableInstance.Rows(CustomerRowIndex).Item(fieldName.Substring(4))
                    Case "Ord"
                        fieldValue = Inv_InvoiceDataTableInstance.Rows(InvoiceRowIndex).Item(fieldName)
                    Case "Inv"
                        fieldValue = Ord_OrderDataTableInstance.Rows(OrderRowIndex).Item(fieldName)
                End Select

                targetText = targetText.Replace(tag, fieldValue)

            End If
        Next
        'targetText.ToString() .... use this to replace the original text in the document
    End Sub

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
msglAuthor Commented:
Hi SiliconXP,

The case statement doesn't work very well, I tried bot the one using substring and the one I posted with fieldName.StartsWith("Cus")
If I don't use the case statement and just to try something by writing:

 tableName = fieldName.ToString
 fieldValue = fieldName.ToString
 fieldValue = Cus_CustomerDataTableInstance.Rows(CustomerRowIndex).Item(fieldName)

I get what I want if I only have parameters from the customer datatable in the richtextbox

But if I use the case statement the application only returns the columns name, ie. {Cus_ID} gets converted to Cus_ID
{Inv_cus_id} gets converted to Inv_cus_id and so on ( by using startsWith).

If I use
                    tableName = fieldName.Substring(fieldName.IndexOf("_"))
                    fieldValue = fieldName.Substring(fieldName.IndexOf("_"))
            
            Select Case tableName
                    Case "Cus"
                        fieldValue = Cus_CustomerDataTableInstance.Rows(CustomerRowIndex).Item(fieldName.Substring(4))

{cus_id} gets converted to _id and so on.

I should be close now but do you have any more suggestion?

Your help is very much appreciated.
0
msglAuthor Commented:
Ok, this solved it

                    tableName = fieldName.ToString
                    fieldValue = fieldName.ToString

                    If tableName.StartsWith("Inv") Then
                        fieldValue = Inv_InvoiceDataTableInstance.Rows(ActivityRowIndex).Item(fieldName)
                    End If
                    If tableName.StartsWith("Cus") Then
                        fieldValue = Cus_CustomerDataTableInstance.Rows(CustomerRowIndex).Item(fieldName)
                    End If

                    If tableName.StartsWith("Ord") Then
                        fieldValue = Ord_OrderDataTableInstance.Rows(OrderRowIndex).Item(fieldName)
                    End If
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.