原创|使用教程|编辑:龚雪|2017-08-22 16:00:55.000|阅读 457 次
概述:传统.NET界面有一个富文本控件RichTextBox,在DevExpress控件组里面也有一个同等的控件——RichEditControl
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
这个例子讲了一个比较老的方法。通过DOCVARIABLE字段,用RichEditDocumentServer创建主从文档。
该项目使用由DevExpress示例nwind.xml文件提供的的二级Categories - Products分层数据源。得到的文件如下所示:
DataClasses.cs
using System; using System.Collections.Generic; using System.Text; using System.Collections; using System.ComponentModel; using System.Linq; namespace MasterDetailExample { public class SupplierCollection : ArrayList, ITypedList { PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) { if (listAccessors != null && listAccessors.Length > 0) { PropertyDescriptor listAccessor = listAccessors[listAccessors.Length - 1]; if (listAccessor.PropertyType.Equals(typeof(ProductCollection))) return TypeDescriptor.GetProperties(typeof(Product)); else if (listAccessor.PropertyType.Equals(typeof(OrderDetailCollection))) return TypeDescriptor.GetProperties(typeof(OrderDetail)); } return TypeDescriptor.GetProperties(typeof(Supplier)); } string ITypedList.GetListName(PropertyDescriptor[] listAccessors) { return "Suppliers"; } } public class Supplier { static int nextID = 0; int id; string name; ProductCollection products = new ProductCollection(); public ProductCollection Products { get { return products; } } public int SupplierID { get { return id; } } public string CompanyName { get { return name; } } public Supplier(string name) { this.name = name; this.id = nextID; nextID++; } public void Add(Product product) { products.Add(product); } } public class ProductCollection : ArrayList, ITypedList { PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) { return TypeDescriptor.GetProperties(typeof(Product)); } string ITypedList.GetListName(PropertyDescriptor[] listAccessors) { return "Products"; } } public class Product { static int nextID = 0; OrderDetailCollection orderDetails = new OrderDetailCollection(); int suppID; int prodID; string name; public int SupplierID { get { return suppID; } } public int ProductID { get { return prodID; } } public string ProductName { get { return name; } } public OrderDetailCollection OrderDetails { get { return orderDetails; } } public Product(int suppID, string name) { this.suppID = suppID; this.name = name; this.prodID = nextID; nextID++; } } public class OrderDetailCollection : ArrayList, ITypedList { PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) { return TypeDescriptor.GetProperties(typeof(OrderDetail)); } string ITypedList.GetListName(PropertyDescriptor[] listAccessors) { return "OrderDetails"; } } public class OrderDetail { int prodID; string orderID; short quantity; public int ProductID { get { return prodID; } } public string OrderID { get { return orderID; } } public short Quantity { get { return quantity; } } public OrderDetail(int prodID, string orderID, int quantity) { this.prodID = prodID; this.orderID = orderID; this.quantity = Convert.ToInt16(quantity); } } }
DataHelper.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MasterDetailExample { class DataHelper { public static SupplierCollection CreateData() { SupplierCollection suppliers = new SupplierCollection(); Supplier supplier = new Supplier("Exotic Liquids"); suppliers.Add(supplier); supplier.Add(CreateProduct(supplier.SupplierID, "Chai")); supplier.Add(CreateProduct(supplier.SupplierID, "Chang")); supplier.Add(CreateProduct(supplier.SupplierID, "Aniseed Syrup")); supplier = new Supplier("New Orleans Cajun Delights"); suppliers.Add(supplier); supplier.Add(CreateProduct(supplier.SupplierID, "Chef Anton's Cajun Seasoning")); supplier.Add(CreateProduct(supplier.SupplierID, "Chef Anton's Gumbo Mix")); supplier = new Supplier("Grandma Kelly's Homestead"); suppliers.Add(supplier); supplier.Add(CreateProduct(supplier.SupplierID, "Grandma's Boysenberry Spread")); supplier.Add(CreateProduct(supplier.SupplierID, "Uncle Bob's Organic Dried Pears")); supplier.Add(CreateProduct(supplier.SupplierID, "Northwoods Cranberry Sauce")); return suppliers; } static Random random = new Random(5); public static Product CreateProduct(int supplierID, string productName) { Product product = new Product(supplierID, productName); product.OrderDetails.AddRange(new OrderDetail[] { new OrderDetail(product.ProductID, GetRandomString(), random.Next(0, 100)), new OrderDetail(product.ProductID, GetRandomString(), random.Next(0, 100)), new OrderDetail(product.ProductID, GetRandomString(), random.Next(0, 100)) }); return product; } public static List<int> CreateFakeDataSource() { List<int> result = new List<int>(); result.Add(0); return result; } public static string GetRandomString() { string path = System.IO.Path.GetRandomFileName(); path = path.Replace(".", ""); return path; } } }
Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using DevExpress.XtraRichEdit; using DevExpress.XtraTab; using DevExpress.XtraRichEdit.API.Native; using System.Collections; namespace MasterDetailExample { public partial class Form1 : Form { SupplierCollection ds; ProductCollection dataDetailedForProducts; OrderDetailCollection dataDetailedForOrders; static List<int> fakeDataSource = DataHelper.CreateFakeDataSource(); int supplierID = -1; int productID = -1; public Form1() { InitializeComponent(); // Associate RichEditControls with TabPages xtraTabPage1.Tag = mainRichEdit; xtraTabPage2.Tag = suppllierRichEdit; xtraTabPage3.Tag = productRichEdit; xtraTabPage4.Tag = ordersRichEdit; xtraTabControl1.SelectedPageChanged+=new TabPageChangedEventHandler(xtraTabControl1_SelectedPageChanged); // Subscribe to the CalculateDocumentVariable event that triggers the master-detail report generation resultRichEdit.CalculateDocumentVariable += new CalculateDocumentVariableEventHandler(resultRichEdit_CalculateDocumentVariable); // Load main template mainRichEdit.LoadDocument("main.rtf"); // Create project's data source ds = DataHelper.CreateData(); // Load templates and specify data sources for RichEdit controls. These data sources facilitate inserting merge fields //by using the Insert Merge Fields button in Ribbon UI. suppllierRichEdit.LoadDocument("supplier.rtf"); suppllierRichEdit.Options.MailMerge.DataSource = ds; productRichEdit.LoadDocument("detail.rtf"); productRichEdit.Options.MailMerge.DataSource = ds; productRichEdit.Options.MailMerge.DataMember = "Products"; ordersRichEdit.LoadDocument("detaildetail.rtf"); ordersRichEdit.Options.MailMerge.DataSource = ds; ordersRichEdit.Options.MailMerge.DataMember = "Products.OrderDetails"; // Display data using XtraGrid control. gridControl1.DataSource = ds; } #region #startmailmerge // Start the process by merging the main template into the document contained within the resultRichEdit control. private void performMailMergeItem1_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { // Since the main template contains no merge fields that require merge data, provide a mock data source. // Otherwise, mail merge will not start. mainRichEdit.Options.MailMerge.DataSource = fakeDataSource; // Trigger the multistage process. After the first mailmerge the CalculateDocumentVariable event //for the resultRichEdit control fires. mainRichEdit.MailMerge(resultRichEdit.Document); xtraTabControl1.SelectedTabPage = xtraTabPage5; } #endregion #startmailmerge #region #secondstage // Second stage. For each Supplier ID, create a detailed document that will be inserted in place of the DOCVARIABLE field. void resultRichEdit_CalculateDocumentVariable(object sender, CalculateDocumentVariableEventArgs e) { if (e.VariableName == "Supplier") { // Create a text engine to process a document after the mail merge. RichEditDocumentServer richServerMaster = new RichEditDocumentServer(); // Provide a procedure for further processing. richServerMaster.CalculateDocumentVariable += richServerMaster_CalculateDocumentVariable; // Create a merged document using the Supplier template. The document will contain DOCVARIABLE fields with ProductID arguments. // The CalculateDocumentVariable event for the richServerMaster fires. suppllierRichEdit.MailMerge(richServerMaster); richServerMaster.CalculateDocumentVariable -= richServerMaster_CalculateDocumentVariable; // Return the document to insert. e.Value = richServerMaster.Document; // Required to use e.Value. Otherwise it will be ignored. e.Handled = true; } } #endregion #secondstage #region #thirdstage // Third stage. For each Product ID, create a detailed document that will be inserted in place of the DOCVARIABLE field. void richServerMaster_CalculateDocumentVariable(object sender, CalculateDocumentVariableEventArgs e) { int currentSupplierID = GetID(e.Arguments[0].Value); if (currentSupplierID == -1) return; if (supplierID != currentSupplierID) { // Get the data source that contains products for the specified supplier. dataDetailedForProducts = GetProductsDataFilteredbySupplier(currentSupplierID); supplierID = currentSupplierID; } if (e.VariableName == "Product") { // Create a text engine to process a document after the mail merge. RichEditDocumentServer richServerDetail = new RichEditDocumentServer(); // Specify the data source for the mail merge. MailMergeOptions options = productRichEdit.CreateMailMergeOptions(); options.DataSource = dataDetailedForProducts; // Specify that the resulting table should be joined with the header table. // Do not specify this option if calculated fields are not within table cells. options.MergeMode = MergeMode.JoinTables; // Provide a procedure for further processing. richServerDetail.CalculateDocumentVariable += richServerDetail_CalculateDocumentVariable; // Create a merged document using the Product template. The document will contain DOCVARIABLE fields with OrderID arguments. // The CalculateDocumentVariable event for the richServerDetail fires. productRichEdit.MailMerge(options, richServerDetail); richServerDetail.CalculateDocumentVariable -= richServerDetail_CalculateDocumentVariable; // Return the document to insert. e.Value = richServerDetail.Document; // This setting is required for inserting e.Value into the source document. Otherwise it will be ignored. e.Handled = true; } } #endregion #thirdstage #region #fourthstage // Fourth stage. For each Order ID, create a detailed document that will be inserted in place of the DOCVARIABLE field. // This is the final stage. The Product.Orders template does not contain DOCVARIABLE fields, so further processing is not required. void richServerDetail_CalculateDocumentVariable(object sender, CalculateDocumentVariableEventArgs e) { int currentProductID = GetID(e.Arguments[0].Value); if (currentProductID == -1) return; if (productID != currentProductID) { // Get the data source that contains orders for the specified product. // The data source is obtained from the data already filtered by Supplier. dataDetailedForOrders = GetOrderDataFilteredbyProductAndSupplier(currentProductID); productID = currentProductID; } if (e.VariableName == "OrderDetails") { RichEditDocumentServer richServerDetailDetail = new RichEditDocumentServer(); MailMergeOptions options = ordersRichEdit.CreateMailMergeOptions(); options.DataSource = dataDetailedForOrders; options.MergeMode = MergeMode.JoinTables; ordersRichEdit.MailMerge(options, richServerDetailDetail); e.Value = richServerDetailDetail.Document; e.Handled = true; } } #endregion #fourthstage #region Helper Methods void xtraTabControl1_SelectedPageChanged(object sender, TabPageChangedEventArgs e) { // Specify a new target for the Ribbon interface - the RichEditControl that is currently active. RichEditControl richEditControl = (RichEditControl)xtraTabControl1.SelectedTabPage.Tag; richEditBarController1.RichEditControl = richEditControl; } protected internal virtual ProductCollection GetProductsDataFilteredbySupplier(int supplierID) { ProductCollection products = new ProductCollection(); foreach (Supplier s in ds) { if (s.SupplierID == supplierID) { products.AddRange(s.Products); } } return products; } protected internal virtual OrderDetailCollection GetOrderDataFilteredbyProductAndSupplier(int productID) { OrderDetailCollection orders = new OrderDetailCollection(); foreach (Product p in dataDetailedForProducts) { if (p.ProductID == productID) { orders.AddRange(p.OrderDetails); } } return orders; } protected internal virtual int GetID(string value) { int result; if (Int32.TryParse(value, out result)) return result; return -1; } #endregion Helper Methods } }
想要速成DevExpress大师?秘籍在这里→
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@cahobeh.cn