彩票走势图

[代码示例]如何在RichEditControl中创建主从报表

原创|使用教程|编辑:龚雪|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大师?秘籍在这里→


标签:DevExpress

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@cahobeh.cn


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP