Skip to content

Commit f2c0506

Browse files
committed
upgrade project
1 parent 08553c9 commit f2c0506

36 files changed

+11420
-19590
lines changed

CS/App.config

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<configSections>
4+
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System">
5+
<section name="DevExpress.LookAndFeel.Design.AppSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
6+
</sectionGroup>
7+
</configSections>
8+
<applicationSettings>
9+
<DevExpress.LookAndFeel.Design.AppSettings>
10+
<setting name="DefaultAppSkin" serializeAs="String">
11+
<value>Skin/WXI</value>
12+
</setting>
13+
<setting name="DefaultPalette" serializeAs="String">
14+
<value></value>
15+
</setting>
16+
<setting name="TouchUI" serializeAs="String">
17+
<value></value>
18+
</setting>
19+
<setting name="CompactUI" serializeAs="String">
20+
<value></value>
21+
</setting>
22+
<setting name="TouchScaleFactor" serializeAs="String">
23+
<value></value>
24+
</setting>
25+
<setting name="DirectX" serializeAs="String">
26+
<value></value>
27+
</setting>
28+
<setting name="RegisterUserSkins" serializeAs="String">
29+
<value></value>
30+
</setting>
31+
<setting name="RegisterBonusSkins" serializeAs="String">
32+
<value></value>
33+
</setting>
34+
<setting name="FontBehavior" serializeAs="String">
35+
<value></value>
36+
</setting>
37+
<setting name="DefaultAppFont" serializeAs="String">
38+
<value></value>
39+
</setting>
40+
<setting name="DPIAwarenessMode" serializeAs="String">
41+
<value>PerMonitorV2</value>
42+
</setting>
43+
<setting name="CustomPaletteCollection" serializeAs="Xml">
44+
<value />
45+
</setting>
46+
</DevExpress.LookAndFeel.Design.AppSettings>
47+
</applicationSettings>
48+
</configuration>

CS/Data/template-intro.rtf

Lines changed: 4977 additions & 0 deletions
Large diffs are not rendered by default.

CS/Data/template.docx

14.1 KB
Binary file not shown.

CS/Form1.Designer.cs

Lines changed: 320 additions & 842 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CS/Form1.cs

Lines changed: 66 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,104 @@
1-
using DevExpress.XtraBars.Ribbon;
1+
using DevExpress.XtraBars.Ribbon;
22
using DevExpress.XtraRichEdit;
33
using DevExpress.XtraRichEdit.API.Native;
44
using DevExpress.XtraTab;
55
using System;
6-
using System.Collections.Generic;
76
using System.Data;
87
using System.Globalization;
8+
using System.IO;
99

1010
namespace RichEditMasterDetailMailMerge
1111
{
1212
public partial class Form1 : RibbonForm
1313
{
14-
1514
DataSet xmlDataSet;
16-
DataTable products;
17-
DataTable categories;
1815
CultureInfo cultureInfo;
19-
16+
private bool introductionHandled; // flag to ensure Introduction is processed only once
17+
private RichEditDocumentServer? introductionContent; // cached content
2018

2119
public Form1()
2220
{
2321
InitializeComponent();
24-
25-
//Subscribe to the CalculateDocumentVariable event that triggers the master-detail report generation:
26-
resultRichEdit.CalculateDocumentVariable += ResultRichEdit_CalculateDocumentVariable;
2722
cultureInfo = CultureInfo.CreateSpecificCulture("en-US");
2823

29-
//Link all RichEditControls to TabPages:
3024
xtraTabPage1.Tag = mainRichEdit;
31-
xtraTabPage2.Tag = masterRichEdit;
32-
xtraTabPage3.Tag = detailRichEdit;
33-
xtraTabPage4.Tag = resultRichEdit;
34-
}
35-
private void Form1_Load(object sender, EventArgs e)
36-
{
37-
//Load main template, master and detail documents to the corresponding RichEditControls:
38-
mainRichEdit.LoadDocument("Templates\\Template.rtf");
39-
masterRichEdit.LoadDocument("Templates\\Master.rtf");
40-
detailRichEdit.LoadDocument("Templates\\Detail.rtf");
25+
xtraTabPage2.Tag = resultRichEdit;
26+
27+
mainRichEdit.LoadDocument("Data//template.docx");
4128

42-
//Initialize and fill the dataset:
4329
xmlDataSet = new DataSet();
4430
xmlDataSet.ReadXml("nwind.xml");
45-
46-
//Fill the required data tables:
47-
categories = xmlDataSet.Tables["Categories"];
48-
products = xmlDataSet.Tables["Products"];
31+
xmlDataSet.Tables["Categories"].PrimaryKey = new DataColumn[] { xmlDataSet.Tables["Categories"].Columns["CategoryID"] };
4932
}
5033

51-
#region #start
5234
private void barButtonItem1_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
5335
{
54-
//The mail merge won't start without a data source. The main template do not require using any data,
55-
//so provide it with a mock data.
56-
mainRichEdit.Options.MailMerge.DataSource = CreateFakeDataSource();
57-
58-
//Start the mail merging process and pass the result to the resultRichEdit.
59-
//When the mail merge starts, the CalculateDocumentVariable raises:
60-
mainRichEdit.MailMerge(resultRichEdit.Document);
61-
62-
xtraTabControl1.SelectedTabPage = xtraTabPage4;
63-
}
64-
#endregion #start
65-
66-
#region #master
67-
private void ResultRichEdit_CalculateDocumentVariable(object sender, CalculateDocumentVariableEventArgs e)
68-
{
69-
//Check whether the event is raised to the required field:
70-
if (e.VariableName == "Categories")
71-
{
72-
//Provide the data source for the next document part:
73-
masterRichEdit.Options.MailMerge.DataSource = categories;
74-
75-
//Create a new RichEditDocumentServer for further processing:
76-
IRichEditDocumentServer result = masterRichEdit.CreateDocumentServer();
77-
78-
//Subscribe the new instance to the CalculateDocumentVariable event to handle the detail part:
79-
result.CalculateDocumentVariable += result_CalculateDocumentVariable;
80-
81-
//Set additional mail merge options if necessary:
82-
MailMergeOptions options = masterRichEdit.CreateMailMergeOptions();
83-
options.LastRecordIndex = 4;
84-
85-
//Merge the document and pass it to the RichEditDocumentServer:
86-
masterRichEdit.MailMerge(options, result.Document);
87-
result.CalculateDocumentVariable -= result_CalculateDocumentVariable;
88-
89-
e.Value = result;
90-
e.Handled = true;
91-
}
92-
93-
}
94-
#endregion #master
95-
96-
#region #detail
97-
private void result_CalculateDocumentVariable(object sender, CalculateDocumentVariableEventArgs e)
98-
{
99-
//Check whether the event is raised for the required field:
100-
if (e.VariableName == "Products")
101-
{
102-
//Provide the detail part with the data source:
103-
detailRichEdit.Options.MailMerge.DataSource = products;
104-
105-
//Create an intermediate document server instance:
106-
IRichEditDocumentServer result = detailRichEdit.CreateDocumentServer();
36+
MailMergeOptions mailMergeOptions = mainRichEdit.CreateMailMergeOptions();
37+
mailMergeOptions.DataSource = xmlDataSet;
38+
mailMergeOptions.DataMember = "Categories";
39+
mailMergeOptions.MergeMode = MergeMode.NewSection;
40+
mailMergeOptions.LastRecordIndex = 10;
41+
resultRichEdit.CalculateDocumentVariable += detail_CalculateDocumentVariable;
42+
mainRichEdit.MailMerge(mailMergeOptions, resultRichEdit.Document);
10743

108-
//Set the merged ranges delimitation and a number of records to be merged:
109-
MailMergeOptions options = detailRichEdit.CreateMailMergeOptions();
110-
options.MergeMode = MergeMode.JoinTables;
111-
options.LastRecordIndex = 10;
11244

113-
//Provide a procedure for further processing:
114-
result.CalculateDocumentVariable += detail_CalculateDocumentVariable;
115-
116-
// Create a merged document with a detail template:
117-
detailRichEdit.MailMerge(options, result.Document);
118-
result.CalculateDocumentVariable -= detail_CalculateDocumentVariable;
119-
120-
e.Value = result;
121-
e.Handled = true;
122-
}
123-
124-
125-
//Format other merged fields:
126-
if (e.VariableName == "LowestPrice")
127-
{
128-
e.Value = String.Format(cultureInfo, "{0:C2}", products.Compute("Min(UnitPrice)", String.Empty));
129-
e.Handled = true;
130-
}
131-
if (e.VariableName == "HighestPrice")
132-
{
133-
e.Value = String.Format(cultureInfo, "{0:C2}", products.Compute("Max(UnitPrice)", String.Empty));
134-
e.Handled = true;
135-
}
136-
if (e.VariableName == "ItemsCount")
137-
{
138-
e.Value = products.Rows.Count;
139-
e.Handled = true;
140-
}
45+
xtraTabControl1.SelectedTabPage = xtraTabPage2;
14146
}
142-
#endregion #detail
14347

144-
#region #UnitPrice
14548
void detail_CalculateDocumentVariable(object sender, CalculateDocumentVariableEventArgs e)
14649
{
147-
int productId = GetID(e.Arguments[0].Value);
148-
if (productId == -1)
149-
return;
150-
151-
//Format the UnitPrice field:
152-
if (e.VariableName == "UnitPrice")
50+
switch (e.VariableName)
15351
{
154-
string expression = String.Format("ProductID = {0}", productId);
155-
e.Value = String.Format(cultureInfo, "{0:C2}", products.Select(expression)[0]["UnitPrice"]);
156-
e.Handled = true;
52+
case "ItemsNumber":
53+
int itemCount = xmlDataSet.Tables["Products"].Select("CategoryID=" + GetID(e.Arguments[0].Value)).Length;
54+
e.Value = itemCount;
55+
e.Handled = true;
56+
break;
57+
case "Picture":
58+
DataRow? row = xmlDataSet.Tables["Categories"].Rows.Find(GetID(e.Arguments[0].Value));
59+
byte[] imageBytes = row?["Picture"] as byte[];
60+
61+
if (imageBytes != null)
62+
{
63+
var imageProcessor = new RichEditDocumentServer();
64+
65+
Shape image = imageProcessor.Document.Shapes.InsertPicture(
66+
imageProcessor.Document.Range.Start,
67+
DocumentImageSource.FromStream(new MemoryStream(imageBytes))
68+
);
69+
image.TextWrapping = TextWrappingType.InLineWithText;
70+
71+
// Set the RichEditDocumentServer with prepared content as the field value.
72+
e.Value = imageProcessor;
73+
e.Handled = true;
74+
}
75+
else
76+
{
77+
// No image found.
78+
e.Value = null;
79+
}
80+
break;
81+
case "Introduction":
82+
// Only handle once. Subsequent occurrences will produce empty content.
83+
if (!introductionHandled)
84+
{
85+
introductionContent = new RichEditDocumentServer();
86+
introductionContent.Document.AppendDocumentContent("Data//template-intro.rtf");
87+
e.Value = introductionContent;
88+
e.Handled = true;
89+
introductionHandled = true;
90+
}
91+
else
92+
{
93+
// Return empty string (or could skip handling). We handle to suppress further processing.
94+
e.Value = DocVariableValue.Current;
95+
e.Handled = true;
96+
}
97+
break;
15798
}
99+
158100
}
159-
#endregion #UnitPrice
160101

161-
#region #Help
162102
protected internal virtual int GetID(string value)
163103
{
164104
int result;
@@ -173,12 +113,6 @@ void tabControl_SelectedPageChanged(object sender, TabPageChangedEventArgs e)
173113
richEditBarController1.RichEditControl = richEditControl;
174114

175115
}
176-
static List<int> CreateFakeDataSource()
177-
{
178-
List<int> result = new List<int>();
179-
result.Add(0);
180-
return result;
181-
}
182-
#endregion #Help
116+
183117
}
184-
}
118+
}

0 commit comments

Comments
 (0)