TX Text Control provides a ready-to-use Ribbon bar with fully functional ribbon tabs for various tasks including the Ribbon ╰ TX Text Control .NET for Windows Forms
╰ Windows.Forms.Ribbon Namespace
╰ RibbonReportingTab Class
The RibbonReportingTab class represents a Windows Forms ribbon tab to integrate mail merge and reporting functionality. to include reporting features.
The RibbonReportingTab can be connected to a Data ╰ TX Text Control .NET for Windows Forms
╰ DocumentServer.DataSources Namespace
╰ DataSourceManager Class
The DataSourceManager class is designed for handling all existing kinds of data sources which can be used together with the MailMerge class. object that encapsulates the complete handling, logic and ready-to-use dialog boxes for the reporting template creation task.
When loading a data source into the DataSourceManager, the data structure is used to fill the Insert Merge Field drop-down lists. Consider the following simple JSON data object:
[ | |
{ | |
"Id": 1, | |
"Customer": { | |
"Id": 1, | |
"Name": "Text Control, LLC", | |
"Street": "6926 Shannon-Willow Rd", | |
"ZipCode": "28226", | |
"City": "Charlotte", | |
"Country": "United States", | |
"Contacts": [ | |
{ | |
"Id": 1, | |
"Name": "Paul De Wright" | |
} | |
] | |
} | |
} | |
] |
When loaded using the DataSourceManager, the drop-down list displays the data column names:
Even if the data column names in this example are not really cryptic, real-world database structures and naming can be complex and confusing for end-users. This concept shows how to change the drop-down item display text for merge fields to provide end-users additional information.
The first data row of the data source is used to change the drop-down items with user-friendly strings. The following data source is used in this example:
[ | |
{ | |
"Id": "The Id [Id]", | |
"Customer": { | |
"Id": "Customer Id [Customer/Id]", | |
"Name": "Customer Name [Customer/Name]", | |
"Street": "Customer Street [Customer/Street]", | |
"ZipCode": "Customer Zip Code [Customer/ZipCode]", | |
"City": "Customer City [Customer/City]", | |
"Country": "Customer Country [Customer/Country]", | |
"Contacts": [ | |
{ | |
"Id": "Customer Contacts Id [Customer/Contacts/Id]", | |
"Name": "Customer Contacts Name [Customer/Contacts/Name]" | |
} | |
] | |
} | |
}, | |
{ | |
"Id": 1, | |
"Customer": { | |
"Id": 1, | |
"Name": "Text Control, LLC", | |
"Street": "6926 Shannon-Willow Rd", | |
"ZipCode": "28226", | |
"City": "Charlotte", | |
"Country": "United States", | |
"Contacts": [ | |
{ | |
"Id": 1, | |
"Name": "Paul De Wright" | |
} | |
] | |
} | |
} | |
] |
When changing the strings after the data has been loaded into the DataSourceManager, the drop-down items show user-friendly strings instead of the actual data column names.
dynamic joData = null; | |
private void Form1_Load(object sender, EventArgs e) | |
{ | |
joData = JsonConvert.DeserializeObject(File.ReadAllText("data.json")); | |
ribbonReportingTab1.DataSourceManager.LoadJson(joData.ToString()); | |
ribbonReportingTab1.DataSourceManager.PossibleMergeFieldColumnsChanged += | |
DataSourceManager_PossibleMergeFieldColumnsChanged; | |
MaskDataColumnNames(joData); | |
} | |
private void DataSourceManager_PossibleMergeFieldColumnsChanged(object sender, EventArgs e) | |
{ | |
MaskDataColumnNames(joData); | |
} |
When clicking on a merge field drop-down item, a valid field is inserted with the actual name and not the masked user-friendly string.
The following function can be called after data has been loaded into the DataSourceManager. It finds the Insert Merge Field drop-down button, gets the currently selected master table that is automatically returned by the DataSourceManager and calls the ApplyMaskedString method:
private void MaskDataColumnNames(dynamic data) | |
{ | |
// flatten data object in case of an array | |
if (data.GetType() == typeof(JArray)) | |
data = data[0]; | |
// find merge fields ribbon menu button | |
RibbonMenuButton ctlInsertMergeFields = | |
ribbonReportingTab1.FindItem( | |
RibbonReportingTab.RibbonItem.TXITEM_InsertMergeField) | |
as RibbonMenuButton; | |
// get the selected master table info | |
DataTableInfo dataTableInfo = | |
ribbonReportingTab1.DataSourceManager.MasterDataTableInfo; | |
// select token in data object | |
if (dataTableInfo.TableName != "RootTable") | |
{ | |
data = data.SelectToken("$.." + dataTableInfo.TableName); | |
} | |
// change the strings | |
ApplyMaskedString(ctlInsertMergeFields.DropDownItems, data); | |
} |
The ApplyMaskedString function loops through all merge field drop-down items in order to replace the text property with the first associated data from the first data row in the data source. In case of a child table, the ApplyMaskedString function is called recursively.
private void ApplyMaskedString(RibbonItemCollection ribbonItems, dynamic data) | |
{ | |
// flatten data object in case of an array | |
if (data.GetType() == typeof(JArray)) | |
data = data[0]; | |
// loop through all ribbon items in the "insert merge fields" menu | |
foreach (Control ribbonButton in ribbonItems) | |
{ | |
// in case, the item is a drop-down, call ApplyMaskedString | |
// recursively with a new data object | |
if (ribbonButton is RibbonMenuButton) | |
{ | |
ApplyMaskedString( | |
((RibbonMenuButton)ribbonButton).DropDownItems, | |
data[ribbonButton.Text]); | |
} | |
// in case it is a merge field insert button | |
else if (ribbonButton is RibbonButton) | |
{ | |
// and it is not a separator or title | |
if (!ribbonButton.Name.StartsWith("TXITEM_")) | |
{ | |
// get the data from the first data row | |
var dataValue = data[ribbonButton.Text]; | |
if (dataValue == null) | |
continue; | |
if (dataValue.GetType() == typeof(JValue)) | |
{ | |
// change the actual text | |
ribbonButton.Text = dataValue.Value; | |
} | |
} | |
} | |
} | |
} |
Try this on your own and download the sample from our GitHub repository.