About Inserting a merge field

12 posts, 0 answers
  1. Peter
    Peter avatar
    10 posts
    Member since:
    Oct 2010

    Posted 21 Jul 2011 Link to this post

    In the RichTextBox demo, how do you populate the drop down list of the Insert Merge Field?

    <telerikRibbonBar:RadRibbonGroup Header="Write & Insert Fields">
                        <telerikRibbonBar:RadRibbonToggleButton LargeImage="/Telerik.Windows.Controls.RichTextBoxUI;component/Images/MSOffice/32/HighlightMergeFields.png" telerik:RadRichTextBoxRibbonUI.RichTextCommand="{Binding Path=ToggleMergeFieldsHighlightCommand}" Size="Large" Text="Highlight Merge Fields" />
                        <telerikRibbonBar:RadRibbonDropDownButton CollapseToMedium="WhenGroupIsMedium" LargeImage="/Telerik.Windows.Controls.RichTextBoxUI;component/Images/MSOffice/32/InsertMergeField.png" telerik:RadRichTextBoxRibbonUI.RichTextCommand="{Binding Path=InsertMergeFieldEmptyCommand}" Size="Large" Text="Insert Merge Field" />
                    </telerikRibbonBar:RadRibbonGroup>

    Where do you specify the drop down list of the RadRibbonDropDownButton?

    Thanks
  2. Boby
    Admin
    Boby avatar
    595 posts

    Posted 22 Jul 2011 Link to this post

    Hello Peter,
    The content of the drop down in filled in the RadRichTextBoxRibbonUI.RichTextCommand attached property. The method used is MailMergeDataSource.GetColumns:
    string[] columnNames = this.radRichTextBox.Document.MailMergeDataSource.GetColumnNames();

    Kind regards,
    Boby
    the Telerik team

    Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

  3. DevCraft banner
  4. John
    John avatar
    9 posts
    Member since:
    May 2014

    Posted 02 Jan 2015 in reply to Boby Link to this post

    Hi Boby, I'm using GetColumnNames like you show but that sorts the fields alphabetically.  How do I bring back my collection in the same order as they are assigned?  DropDownReferral is a class containing strings.  I.e.

    class DropDownReferral
    {
    public string DateOfReferral { get; set; }
    public string AuthNo { get; set; }
    public string RefExpirationDate { get; set; }
    public string NoAuthVisits { get; set; }
    public string ReasonForReferral { get; set; }
    }

    My current code looks like this:
    List<DropDownReferral> refDropDown = new List<DropDownReferral>();
    this.editor.Document.MailMergeDataSource.ItemsSource = refDropDown;
    AddFieldsInDropDownContent(sender as RadRibbonDropDownButton);
    }

    private void AddFieldsInDropDownContent(RadRibbonDropDownButton radRibbonDropDownButton)
    {
    ScrollViewer myScrollViewer = new ScrollViewer();
    myScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
    StackPanel stackPanel = new StackPanel();

    foreach (string fieldName in this.editor.Document.MailMergeDataSource.GetColumnNames())
    {
    RadRibbonButton fieldButton = new RadRibbonButton()
    {
    Text = fieldName,
    Size = ButtonSize.Medium,
    HorizontalAlignment = HorizontalAlignment.Stretch,
    HorizontalContentAlignment = HorizontalAlignment.Left
    };

    fieldButton.Command = this.editor.Commands.InsertFieldCommand;
    fieldButton.CommandParameter = new MergeField() { PropertyPath = fieldName };

    stackPanel.Children.Add(fieldButton);
    }
    stackPanel.Width = 140;

    myScrollViewer.Content = stackPanel;

    radRibbonDropDownButton.DropDownContent = myScrollViewer;
    }
  5. Boby
    Admin
    Boby avatar
    595 posts

    Posted 05 Jan 2015 Link to this post

    Hi John,
    You are right, GetColumnNames method sorts the names in alphabetic order, and currently this cannot be configured.

    I can suggest you to use plain reflection instead - this would get the properties in the order of declaration:
    foreach (string fieldName in typeof(DropDownReferral).GetProperties().Select(p => p.Name))
    {
        // ...
    }


    Regards,
    Boby
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  6. John
    John avatar
    9 posts
    Member since:
    May 2014

    Posted 06 Jan 2015 in reply to Boby Link to this post

    Thanks Bobby, this does sort properly for this particular class, DropDownReferral.  But I have several classes tied to several DropDowns.  Previously, I set MailMergeDataSource.ItemsSource before coming to AddFieldsInDropDownContent so each DropDownButton showed the corresponding Properties or Columns.  For example, another click event will also call AddFieldsInsDropDownContent and I need it to get the properties for that DropDown class, DropDownPatient in this example:
           
    public void patFields_Click(object sender, RoutedEventArgs e)
    {
    List<DropDownPatient> patDropDownList = new List<DropDownPatient>();
    this.editor.Document.MailMergeDataSource.ItemsSource = patDropDownList;
    AddFieldsInDropDownContent(sender as RadRibbonDropDownButton);
    }

    Is there a way to dynamically set which class I am retrieving the "GetProperties" from so that all click events can use this same AddFieldsInDropDownContent method? 
  7. John
    John avatar
    9 posts
    Member since:
    May 2014

    Posted 06 Jan 2015 in reply to Boby Link to this post

    Bobby, I think I solved this by using reflection to get the class name and then set the type with that name.  Here are the basics fyi but please let me know if there is a more efficient way. This way seems good but someone mentioned using interfaces.   


    fullClassName = typeof(DropDownPatient).FullName;
    .
    .
    Type type = System.Reflection.TypeInfo.GetType(fullClassName);

    foreach (string fieldName in type.GetProperties().Select(p => p.Name))
    .
    .

    One thing I still see though is that when I select something from the DropDown control, the FieldsName is added to the doc, but the drop down does not go away until I click somewhere on the doc.  This is not how your demo works.  I am using the "CommandExecutingEventArgs" event. Do I need to explicitly close the drop down somehow? 
  8. John
    John avatar
    9 posts
    Member since:
    May 2014

    Posted 07 Jan 2015 in reply to John Link to this post

    Hey Boby, Petya helped me in adding this CommandExecutingEvent to the drop down to force it to insert the Fields Names instead of the Fields Codes.  Because I'm using this command executing event, do I need to somehow explicitly "hide" the drop down now?  I don't find a command to do this and it is down automatically if I don't use this command execute event. 

            void editor_CommandExecuting(object sender, Telerik.Windows.Documents.RichTextBoxCommands.CommandExecutingEventArgs e)
    {

    if (e.Command is InsertFieldCommand && e.CommandParameter is MergeField)
    {
    string fieldName = (e.CommandParameter as MergeField).PropertyPath;

    e.Cancel = true;
    MergeField mf = new MergeField();
    mf.PropertyPath = fieldName;

    //this.editor.InsertField(mf);
    this.editor.InsertField(mf, FieldDisplayMode.DisplayName);
    }
    }
  9. Petya
    Admin
    Petya avatar
    975 posts

    Posted 09 Jan 2015 Link to this post

    Hello John,

    If the binding to the InsertFieldCommand is in place and you are using the CommandExecuting event to handle the insertion of a field, the drop-down should be closed as expected. 
    <telerik:RadRibbonDropDownButton CollapseToMedium="WhenGroupIsMedium" telerik:ScreenTip.Description="You can insert fields such as Name or Address, which will be replaced automatically with information from a database or contact list for each copy of the form letter." LargeImage="pack://application:,,,/Telerik.Windows.Controls.RichTextBoxUI;component/Images/MSOffice/32/InsertMergeField.png" telerik:RadRichTextBoxRibbonUI.RichTextCommand="{Binding InsertMergeFieldEmptyCommand}" Size="Large" Text="Insert Merge Field" telerik:ScreenTip.Title="Insert Merge Field"/>

    However, if you've removed the binding and are populating the drop-down from code, you'd need to handle the closing yourself. For example, attach to the button's DropDownOpening event and execute the population there:
    <telerik:RadRibbonDropDownButton Name="myFields" Text="Some Fields" DropDownOpening="myFields_DropDownOpening"/>
    And in code-behind:
    private void myFields_DropDownOpening(object sender, RoutedEventArgs e)
    {
        StackPanel stackPanel = new StackPanel();
        (sender as RadRibbonDropDownButton).DropDownContent = stackPanel;
     
        //...
    }

    Let me know how this works for you.

    Regards,
    Petya
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  10. John
    John avatar
    9 posts
    Member since:
    May 2014

    Posted 13 Jan 2015 in reply to Petya Link to this post

    Hi Petya, yes this worked.  I had the binding removed and was doing it the way you described above except I was populating the code from the "Click" event instead of from "DropDownOpening".  When I changed to "DropDownOpening", it now closes but I'm not sure why.  I couldn't find a list that describes all events. 

    But there is still one problem.  When I add the merge field into the document from the DropDownButton it shows fine.  But if I save the document and then go back into it, the merge fields do not show at all; the document appears blank.  But if I then go to the Mailings Tab and press "Show All Fields Names" the merge fields then show properly. 

    I've attached the .docx file in case that helps. 

    Here is the xaml and event code for DropDownOpening (was Click):
    <telerik:RadRibbonDropDownButton VerticalAlignment="Top" Name="patFields" DropDownOpening="patFields_Click" Text="Patient Info" />

    public void patFields_Click(object sender, RoutedEventArgs e)
    {
    List<DropDownPatient> patDropDownList = new List<DropDownPatient>();
    this.editor.Document.MailMergeDataSource.ItemsSource = patDropDownList;
    fullClassName = typeof(DropDownPatient).FullName;
    AddFieldsInDropDownContent(sender as RadRibbonDropDownButton);
    }

    private void AddFieldsInDropDownContent(RadRibbonDropDownButton radRibbonDropDownButton)
    {
    ScrollViewer myScrollViewer = new ScrollViewer();
    myScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
    StackPanel stackPanel = new StackPanel();

    Type type = System.Reflection.TypeInfo.GetType(fullClassName);

    //foreach (string fieldName in this.editor.Document.MailMergeDataSource.GetColumnNames()) *** SORTS ALPHABETICALLY ***
    foreach (string fieldName in type.GetProperties().Select(p => p.Name))
    {
    RadRibbonButton fieldButton = new RadRibbonButton()
    {
    Text = fieldName,
    Size = ButtonSize.Medium,
    HorizontalAlignment = HorizontalAlignment.Stretch,
    HorizontalContentAlignment = HorizontalAlignment.Left
    };

    fieldButton.Command = this.editor.Commands.InsertFieldCommand;
    fieldButton.CommandParameter = new MergeField() { PropertyPath = fieldName };

    stackPanel.Children.Add(fieldButton);
    }

    stackPanel.Width = 140;

    myScrollViewer.Content = stackPanel;

    radRibbonDropDownButton.DropDownContent = myScrollViewer;
    }

    Here is the code for CommandExecuting:
    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
    RadDocument document = null;
    IDocumentFormatProvider provider = new DocxFormatProvider();
               
    using (FileStream stream = new FileStream(holdDocName, FileMode.Open))
    {
    document = provider.Import(stream);
    }

    this.editor.Document = document;

    this.editor.CommandExecuting += editor_CommandExecuting;
    }

    void editor_CommandExecuting(object sender, Telerik.Windows.Documents.RichTextBoxCommands.CommandExecutingEventArgs e)
    {
    if (e.Command is InsertFieldCommand && e.CommandParameter is MergeField)
    {
    string fieldName = (e.CommandParameter as MergeField).PropertyPath;

    e.Cancel = true;
    MergeField mf = new MergeField();
    mf.PropertyPath = fieldName;

    //this.editor.InsertField(mf);
    this.editor.InsertField(mf, FieldDisplayMode.DisplayName);
    }
    }


  11. Petya
    Admin
    Petya avatar
    975 posts

    Posted 16 Jan 2015 Link to this post

    Hi John,

    You can try using the export settings of the format provider and specify the display mode of the fields you want to see.
    DocxFormatProvider provider = new DocxFormatProvider(); 
    DocxExportSettings settings = new DocxExportSettings();
    settings.FieldResultMode = FieldDisplayMode.Result; 
    provider.ExportSettings = settings;

    I hope this helps.

    Regards,
    Petya
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  12. John
    John avatar
    9 posts
    Member since:
    May 2014

    Posted 21 Jan 2015 in reply to Petya Link to this post

    Hi Petya, sorry but the mail merge fields are displaying properly at first.  Using the settings does not change anything.  I can insert the Merge Fields and they show fine.  But after saving and exiting, I open the docx file using Word and the Merge Fields do not show.   I know they are actually there though because if I pull the document up again from Telerik and do "Show All Fields Names", they show again. 

    In the SDK Mail merge example, it does not allow the user to save the document after adding new Merge Fields so I can't test that.  You can only save the result after you have run the mail merge.  I need to be able to update these merge templates and save them to be used later.  Any thoughts??

    John
  13. Petya
    Admin
    Petya avatar
    975 posts

    Posted 23 Jan 2015 Link to this post

    Hello John,

    I'm not sure what might be causing this and the code from my previous reply works fine on our end. Please open a new support ticket and attach a project demonstrating your setup and the mentioned issue. We will look into the case and try to provide further assistance.

    We are looking forward to hearing from you.

    Regards,
    Petya
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
Back to Top
DevCraft banner