创建一个专业的ActiveReports报表设计器

没错,ActiveReports Pro 提供了一个Designer控件,也提供了一个EndUserDesigner程序,但功能不近人意,那如何为用户提供一个专业的,易用的 EndUserDesigner呢?

程序名:ReportDesigner 以下简称:RD2

功能特色:
一,友好的Ribbon界面;
二,支持两种设计模式:报表(Report),模板文件(TemplateFile):
      1, ReportMode: 实现对程序内置的报表进行修改;
      2, TemplateFileMode: 通过能够独立运行的设计器对.rpx,.design的报表格式进行创建/修改;
      3, 通过双击.rdf文件直接打开报表预览窗口。
三,实现记住最近使用的设计文档(仅TemplateFile模式),支持按"使用时间;修改时间;扩展名;文件名"进行排序,支持固定索引;
四,支持内建的数据源DataSet对象和更多标准控件到报表设计器;
五,支持类似于Photoshop的快照功能;
六,丰富,直观的报表设置途径。

待改善:
一,单一的设计窗口,暂不支持多窗口设计(MultiWindow);
二,目前快照功能只支持最多三个快照对象(可实现通过设置来决定最多能创建多少个快照对象)。

第三方核心组件:
ActiveReports 3.0 Pro SP2;
DevExpress v8.2.

程序入口:
  1. [STAThread]
  2.         static void Main(string[] args)
  3.         {
  4.             Application.EnableVisualStyles();
  5.             Application.SetCompatibleTextRenderingDefault(false);
  6.             string customInfo;
  7.             string fileName;
  8.             bool reportViewFlag = false;
  9.             if (args.Length > 0)
  10.             {
  11.                 fileName = args[0];
  12.                 string Extension = System.IO.Path.GetExtension(args[0]).ToLower();
  13.                 if (Extension == ".rdf")
  14.                 {
  15.                     reportViewFlag = true;
  16.                     customInfo = "正在打开报表预览:" + args[0] + "...";
  17.                 }
  18.                 else
  19.                     customInfo = "正在设计文档:" + args[0] + "...";
  20.             }
  21.             else
  22.             {
  23.                 customInfo = "正在创建一个空白设计...";
  24.                 fileName = string.Empty;
  25.             }
  26.             if (Common.frmSplash.SplashDone(typeof(ReportDesignerRibbonForm), CIMS.Common.frmSplash.SplashTypeEnum.ReportDesigner, customInfo) == DialogResult.OK)
  27.             {
  28.                 if (reportViewFlag)
  29.                 {
  30.                     ReportViewerForm Viewer = new ReportViewerForm(true);
  31.                     Viewer.ShowInTaskbar = true;
  32.                     Viewer.Text = string.Format("报表预览器 - [{0}]", fileName);
  33.                     Viewer.Activate();
  34.                     Viewer.ReportViewer.ExportToFileClick += ExportToFile_Click;
  35.                     Viewer.ReportViewer.Document.InProgress = true;
  36.                     Viewer.ReportViewer.Document.Load(fileName);
  37.                     CIMS.Document.ReportSettings docSet = new CIMS.Document.ReportSettings();
  38.                     Viewer.ReportViewer.Document.Printer.PrinterName = docSet.PrinterName;
  39.                     CIMS.Document.ReportSettings.PageDirectionEnum pd = Document.BorderStyle.PageDirectionEnum.Horizontal;
  40.                     if (Viewer.ReportViewer.Document.Printer.Landscape == false)
  41.                         pd = Document.BorderStyle.PageDirectionEnum.Vertical;
  42.                     //Viewer.ReportViewer.Document.Printer.DefaultPageSettings.Margins = docSet.get_Margins(pd);
  43.                     Application.Run(Viewer);
  44.                 }
  45.                 else
  46.                 {
  47.                     DevExpress.UserSkins.OfficeSkins.Register();
  48.                     DevExpress.UserSkins.BonusSkins.Register();
  49.                     DevExpress.Utils.AppearanceObject.ControlAppearance.Font = Common.Common.DefaultFont;
  50.                     DevExpress.Utils.AppearanceObject.DefaultFont = Common.Common.DefaultFont;
  51.                     DevExpress.Utils.AppearanceObject.EmptyAppearance.Font = Common.Common.DefaultFont;
  52.                     DevExpress.Skins.SkinManager.EnableFormSkinsIfNotVista();
  53.                     CIMS.Common.Language.InitLanguage();//必须在LocalizationResUtils.InitLanguage()之前调用
  54.                     CIMS.Controls.LocalizationResUtils.InitLanguage();
  55.                     if (CIMS.Common.Language.Active != CIMS.Common.Language.LanguageEnum.English)
  56.                     {
  57.                         DevExpress.XtraNavBar.NavBarLocalizer.Active = new Resources.CustomNavBarLocalizer();
  58.                     }
  59.                     CIMS.Report.Designer.ReportDesignerRibbonForm mainForm = new ReportDesignerRibbonForm(fileName);
  60.                     //Common.InfoProvider.SendInfo += new CIMS.Common.InfoProvider.SendProcessInfoHandler(mainForm.SetProcessInfo);
  61.                     Application.Run(mainForm);
  62.                 }
  63.             }
  64.         }
启动界面:


设计器主界面:



功能实现讲解:

实现设计模式:
报表模式于模板模式不同的是:
1,不能新增报表,但允许导入模式文件;
2,主窗体以Modal方式显示,返回DialogResult值,只能返回DialogResult.OK,才表示需要重新加载报表;
3,原来的“保存”文件成了“保存并关闭”。
4,从RecentMRU列表打开模式文件,将开启一个新的RD2进程来并以TemplateFile模式打开。
  1. public enum DesignerModeEnum
  2.         {
  3.             /// <summary>
  4.             /// RPX文件设计模式
  5.             /// </summary>
  6.             File = 0,
  7.             /// <summary>
  8.             /// 报表设计模式
  9.             /// </summary>
  10.             Report = 1
  11.         }
  12. /// <summary>
  13. /// 获取设计器的设计模式(RPX文件还是报表对象)
  14. /// </summary>
  15. public DesignerModeEnum DesignerMode
  16.         {
  17.             get { return string.IsNullOrEmpty(FileName) ? DesignerModeEnum.Report : DesignerModeEnum.File; }
  18.         }
  19. /// <summary>
  20. /// 获取报表设计状态是否已更改(需要提示保存)
  21. /// </summary>
  22. public bool DesignChanged
  23.         {
  24.             get { return Designer.IsDirty; }
  25.             set
  26.             {
  27.                 if (Designer.IsDirty == value) return;
  28.                 Designer.IsDirty = value;
  29.                 this.SetDesignerModeText();
  30.             }
  31.         }
  32. /// <summary>
  33. /// 获取或设置设计的RPX报表文件
  34. /// </summary>
  35. public string FileName
  36.         {
  37.             get { return m_fileName; }
  38.             set
  39.             {
  40.                 if (m_fileName == value) return;
  41.                 m_fileName = value;
  42.                 this.SetDesignerMode();
  43.             }
  44.         }
  45. /// <summary>
  46.         /// 设置报表设计模式(RPX文件还是报表对象)
  47.         /// </summary>
  48.         protected void SetDesignerMode()
  49.         {
  50.             this.Designer.UndoManager.Clear();
  51.             this.SetDesignerModeText();
  52.             if (this.DesignerMode == DesignerModeEnum.Report)
  53.             {
  54.                 this.barReportNew.Enabled = false;
  55.                 this.barReportOpen.Enabled = false;
  56.                 this.barReportSave.Caption = "保存并预览";
  57.                 this.barReportSave.Hint = "保存设计并在关闭设计器后重新加载报表数据到预览窗口.";
  58.             }
  59.             else
  60.             {
  61.                 this.barReportNew.Enabled = true;
  62.                 this.barReportOpen.Enabled = true;
  63.                 this.barReportSave.Caption = "保存";
  64.                 this.barReportSave.Hint = "保存设计文件 '" + this.FileName + "'";
  65.             }
  66.             this.barReportNewPopup.Enabled = this.barReportNew.Enabled;
  67.             this.barReportSavePopup.Caption = this.barReportSave.Caption;
  68.             this.barReportSavePopup.Hint = this.barReportSave.Hint;
  69.         }
  70.         protected void SetDesignerModeText()
  71.         {
  72.             string text = (this.DesignerMode == DesignerModeEnum.File ? this.FileName : this.DocumentName);
  73.             if (this.DesignChanged) text += " *";
  74.             text += " - 报表设计器 V2";
  75.             this.Text = text;
  76.         }

实现记住最近使用的设计文档:(RecentDesignDocumentsMRU):

类似于Office System 的文档使用历史记录。


设置窗口:


核心实现:
  1.  public enum RecentSortModeEnum
  2.         {
  3.             /// <summary>
  4.             /// 按索引(最近打开时间)
  5.             /// </summary>
  6.             ByIndex = 0,
  7.             /// <summary>
  8.             /// 按最近访问时间
  9.             /// </summary>
  10.             ByLastAccessDateTime = 1,
  11.             /// <summary>
  12.             /// 按最近修改时间
  13.             /// </summary>
  14.             ByLastWriteDateTime = 2,
  15.             /// <summary>
  16.             /// 按文件名
  17.             /// </summary>
  18.             ByFileName=3,
  19.             /// <summary>
  20.             /// 获取设计文件的扩展名(不含.)
  21.             /// </summary>
  22.             ByExtension=4
  23.         }
主窗体调用:
  1. protected string mrfFileName = "RibbonMRURecentFiles.ini";
  2.         protected string MURFieName { get { return Application.StartupPath + "//Settings//" + mrfFileName; } }
  3.         private const char MURSPLITCHAR = ';';
  4.         void InitMostRecentFiles()
  5.         {
  6.             string settingsName = MURFieName;
  7.             if (System.IO.File.Exists(settingsName) == falsereturn;
  8.             System.IO.StreamReader sr = null;
  9.             try
  10.             {
  11.                 sr = System.IO.File.OpenText(settingsName);
  12.                 for (string s = sr.ReadLine(); s != null; s = sr.ReadLine())//每行一个,保存格式:[FileFullName];[Index];[IsIndexFixed]
  13.                 {
  14.                     string[] args = s.Split(MURSPLITCHAR);
  15.                     this.RecentFilesMRU.Add(args[0], Convert.ToInt32(args[1]), Convert.ToBoolean(args[2]));
  16.                 }
  17.             }
  18.             //catch (Exception err) { Common.ExceptionMessenger.OnThrowError("无法从配置文件中获取最近的设计文件列表!", err); }
  19.             finally
  20.             {
  21.                 if (sr != null) sr.Close();
  22.                 this.RecentFilesMRU.IsChanged = false;
  23.             }
  24.         }
  25.         void SaveMostRecentFiles()
  26.         {
  27.             if (this.RecentFilesMRU.IsChanged == falsereturn;
  28.             System.IO.StreamWriter sw = null;
  29.             string settingFile = MURFieName;
  30.             try
  31.             {
  32.                 sw = System.IO.File.CreateText(settingFile);
  33.                 for (int i = RecentFilesMRU.Count - 1; i >= 0; i--)
  34.                 {
  35.                     string fileFullName = RecentFilesMRU[i].ToString();
  36.                     sw.WriteLine(string.Format("{1}{0}{2}{0}{3}", MURSPLITCHAR, fileFullName, i, this.RecentFilesMRU.GetLabelChecked(fileFullName)));
  37.                 }
  38.                 sw.Close();
  39.             }
  40.             catch (Exception err) { Common.ExceptionMessenger.OnThrowError("无法保存最近的设计文件列表到配置文件:'" + settingFile + "'!", err); }
  41.             finally
  42.             {
  43.                 if (sw != null) sw.Close();
  44.             }
  45.         }
  46.         void AddToMostRecentFile()
  47.         {
  48.             this.RecentFilesMRU.InsertElement(this.FileName);
  49.         }
  50.         void OnLabelClicked(object sender, EventArgs e)
  51.         {
  52.             RecentDesignItem selectedItem = (RecentDesignItem)sender;
  53.             if (System.IO.File.Exists(selectedItem.FullName) == false)
  54.             {
  55.                 if (MessageBox.Show("对不起,设计文档 " + Common.Common.GetMasks(selectedItem.FullName) + " 已经改名或删除!要从列表中移除对它的引用吗?""打开设计文档", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) RecentFilesMRU.Remove(selectedItem);
  56.                 return;
  57.             }
  58.             if (this.DesignerMode == DesignerModeEnum.Report)
  59.             {
  60.                 applicationMenu1.HidePopup();
  61.                 this.Refresh();
  62.                 if (MessageBox.Show("对不起!目前为报表设计模式(非文件),您是否希望在新进程中打开它?"this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
  63.                 {
  64.                     System.Diagnostics.Process.Start(Common.Apps.GetAppFilePath(CIMS.Common.frmSplash.SplashTypeEnum.ReportDesigner), selectedItem.FullName);
  65.                 }
  66.                 return;
  67.             }
  68.             bool result = this.OpenReportFile(selectedItem.FullName);
  69.             if (result)
  70.             {
  71.                 applicationMenu1.HidePopup();
  72.                 this.Refresh();
  73.                 this.FileName = selectedItem.FullName;
  74.                 this.AddToMostRecentFile();
  75.             }
  76.         }
实现排序和更新列表:
  1. public event EventHandler RecentDesignItemsSorted=null;
  2.         protected bool m_updated = true;
  3.         public void BeginUpdate() { m_updated = false; }
  4.         public void EndUpdate()
  5.         {
  6.             m_updated = true;
  7.             this.Update();
  8.         }
  9.         /// <summary>
  10.         /// 获取或设置列表的排序模式(并立即排序)
  11.         /// </summary>
  12.         public RecentDesignItemSorter.RecentSortModeEnum SortMode
  13.         {
  14.             get { return m_sortMode; }
  15.             set {
  16.                 if (m_sortMode == value) return;
  17.                 m_sortMode = value;
  18.                 this.Update();
  19.             }
  20.         }
  21.         /// <summary>
  22.         /// 获取或设置列表排序方式(并立即排序)
  23.         /// </summary>
  24.         public SortOrder SortOrder
  25.         {
  26.             get { return m_sortOrder; }
  27.             set
  28.             {
  29.                 if (m_sortOrder == value) return;
  30.                 m_sortOrder = value;
  31.                 this.Update();
  32.             }
  33.         }
  34.         public void Update()
  35.         {
  36.             if (m_updated == falsereturn;
  37.             this.Sort();
  38.             this.OnUpdateRecentDesignItems(EventArgs.Empty);
  39.             m_updated = true;
  40.         }
  41.         public override void Sort()
  42.         {
  43.             //以后可以由用户控制
  44.             base.Sort(new RecentDesignItemSorter(this.SortMode, this.SortOrder));
  45.             if (RecentDesignItemsSorted != null) RecentDesignItemsSorted(this, EventArgs.Empty);
  46.         }
  47.         /// <summary>
  48.         /// 对项目重新排序
  49.         /// </summary>
  50.         /// <param name="e"></param>
  51.         protected void OnUpdateRecentDesignItems(EventArgs e)
  52.         {
  53.             container.Controls.Clear();
  54.             foreach (RecentDesignItem item in this)
  55.             {
  56.                 this.OnCreateToMRU(item,item.IndexFixed);
  57.             }
  58.         }

RecentDesignItemSorter 暂不公开代码.

快照功能:
允许创建或恢复报表设计状态(原理是将报表暂存到MemoryStream,然后用LoadReport(stream)方法载入). 功能待改善.



快照管理窗口,实现快照的创建,删除,选择等操作:


 

  1. public class ReportSnapItem : IDisposable
  2.     {
  3.         protected System.IO.MemoryStream m_reportSnap = null;
  4.         protected DateTime m_createdTime = DateTime.MinValue;
  5.         protected int m_controlsCount = 0;
  6.         protected int m_index = 0;
  7.         public ReportSanpItem(int index) { m_index = index; }
  8.         public ReportSanpItem(DataDynamics.ActiveReports.Design.Designer designer)
  9.         {
  10.             this.ToSanp(designer);
  11.         }
  12.         #region Methods
  13.         /// <summary>
  14.         /// 创建报表快照到MemoryStream
  15.         /// </summary>
  16.         /// <param name="report">报表</param>
  17.         public bool ToSanp(DataDynamics.ActiveReports.Design.Designer designer)
  18.         {
  19.             if (IsCreated)
  20.             {
  21.                 if (MessageBox.Show("快照已存在,您真的要替换这份快照吗?/n快照名:" + string.Format("{0};控件数量:{1};创建时间:{2}"this.ToString(), this.ControlsCount, this.CreatedTime), "保存快照", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) return false;
  22.                 this.ClearSanp();
  23.             }
  24.             m_reportSanp = new MemoryStream();
  25.             designer.Report.SaveLayout(m_reportSanp);
  26.             m_reportSanp.Position = 0;
  27.             
  28.             m_createdTime = DateTime.Now;
  29.             foreach(DataDynamics.ActiveReports.Section section in designer.Report.Sections)
  30.             {
  31.                 m_controlsCount += section.Controls.Count;
  32.             }
  33.             CIMS.Common.InfoProvider.OnInfo(string.Format("'{0}' 已创建!如果不需要请及时清除它。",ToString()),'m');
  34.             return true;
  35.         }
  36.         public bool ResumeSanp(DataDynamics.ActiveReports.Design.Designer designer)
  37.         {
  38.             if (IsCreated == falsereturn false;
  39.             foreach (DataDynamics.ActiveReports.Section section in designer.Report.Sections)
  40.             {
  41.                 section.Controls.Clear();
  42.             }
  43.             try
  44.             {
  45.                  designer.NewReport();//必须先创建一个新的报表设计!AR 的一个BUG
  46.                  designer.LoadReport(this.ReportSanp);
  47.                 CIMS.Common.InfoProvider.OnInfo(string.Format("'{0}' 已恢复!如果不需要请及时清除它。", ToString()), 'm');
  48.                 return true;
  49.             }
  50.             catch (Exception err) { Common.ExceptionMessenger.OnThrowError("无法从 " + this.ToString() + " 中恢复报表快照!",err); return false; }
  51.             finally { }// designer.Report.EndInit(); }
  52.         }
  53.         public ListViewItem CreateToListViewItem()
  54.         {
  55.             ListViewItem item = new ListViewItem(this.ToString());//快照名
  56.             item.SubItems.Add(ControlsCount.ToString());//控件数目
  57.             item.SubItems.Add(CreatedTime == DateTime.MinValue ? string.Empty : CreatedTime.ToString());//创建日期
  58.             if (IsCreated == false) item.ForeColor = Color.Gray;
  59.             item.Tag = this.ReportSanp;
  60.             item.StateImageIndex = 0;
  61.             return item;
  62.         }
  63.          #endregion
  64.         #region Properties
  65.         /// <summary>
  66.         /// 获取报表快照
  67.         /// </summary>
  68.         public System.IO.MemoryStream ReportSanp { get { return m_reportSanp; } }
  69.         /// <summary>
  70.         /// 获取是否已创建了快照
  71.         /// </summary>
  72.         public new bool IsCreated { get { return m_reportSanp != null; } }
  73.         /// <summary>
  74.         /// 获取或设置快照创建时间
  75.         /// </summary>
  76.         public DateTime CreatedTime
  77.         {
  78.             get { return m_createdTime; }
  79.             set { m_createdTime = value; }
  80.         }
  81.         /// <summary>
  82.         /// 获取或设置快照创建前的控件数目
  83.         /// </summary>
  84.         public int ControlsCount
  85.         {
  86.             get { return m_controlsCount; }
  87.             set { m_controlsCount = value; }
  88.         }
  89.         /// <summary>
  90.         /// 获取或设置快照索引
  91.         /// </summary>
  92.         public int Index
  93.         {
  94.             get { return m_index; }
  95.             set { m_index = value; }
  96.         }
  97.         #endregion
  98.         public bool ClearSanp()
  99.         {
  100.             if (m_reportSanp != null)
  101.             {
  102.                 m_reportSanp.Dispose();
  103.                 m_reportSanp = null;
  104.                 return true;
  105.             }
  106.             return false;
  107.         }
  108.         public void Dispose()
  109.         {
  110.             this.ClearSanp();
  111.         }
  112.         public override string ToString()
  113.         {
  114.             return "快照" + Index.ToString();
  115.         }
  116.     }



绘制边框线:


  1. protected override void OnCreateGalleryItems()
  2.         {
  3.             base.OnCreateGalleryItems();
  4.             string[] lineStyles = System.Enum.GetNames(typeof(DataDynamics.ActiveReports.BorderLineStyle));
  5.             foreach (string lineStyle in lineStyles)
  6.             {
  7.                 DataDynamics.ActiveReports.BorderLineStyle style = (DataDynamics.ActiveReports.BorderLineStyle)System.Enum.Parse(typeof(DataDynamics.ActiveReports.BorderLineStyle), lineStyle);
  8.                 GalleryItem gItem = new GalleryItem();
  9.                 gItem.Image = CreateLineStyelToImage(style, DEFAULTWIDTH, DEFAULTHEIGHT);
  10.                 gItem.HoverImage = CreateLineStyelToImage(style, DEFAULTWIDTH_HOVER, DEFAULTHEIGHT_HOVER);
  11.                 gItem.Hint = GetBorderLineStyleStr(style);
  12.                 gItem.Tag = style;
  13.                 if (style == DataDynamics.ActiveReports.BorderLineStyle.Solid) gItem.Checked = true;
  14.                 RibbonGallery.Gallery.Groups[0].Items.Add(gItem);
  15.             }
  16.         }
  17.         private Image CreateLineStyelToImage(DataDynamics.ActiveReports.BorderLineStyle style, Int32 width, Int32 height)
  18.         {
  19.             Bitmap image = new Bitmap(width, height);
  20.             if (style != DataDynamics.ActiveReports.BorderLineStyle.None)
  21.             {
  22.                 using (Graphics g = Graphics.FromImage(image))
  23.                 {
  24.                     Pen pen = this.CreatePen(style);
  25.                     using (pen)
  26.                     {
  27.                         g.DrawLine(pen, 0, image.Height / 2, image.Width, image.Height / 2);
  28.                         switch (style)
  29.                         {
  30.                             case DataDynamics.ActiveReports.BorderLineStyle.Double:
  31.                                 g.DrawLine(pen, 0, image.Height / 2 + 2, image.Width, image.Height / 2 + 2);
  32.                                 break;
  33.                             case DataDynamics.ActiveReports.BorderLineStyle.ThickDouble:
  34.                                 g.DrawLine(pen, 0, image.Height / 2 + 4, image.Width, image.Height / 2 + 4);
  35.                                 break;
  36.                             default:
  37.                                 break;
  38.                         }
  39.                     }
  40.                 }
  41.             }
  42.             return image;
  43.         }
  44.         protected Pen CreatePen(DataDynamics.ActiveReports.BorderLineStyle lineStyle)
  45.         {
  46.             SolidBrush brush = new SolidBrush(this.LineColor);
  47.             Pen pen = new Pen(brush);
  48.             pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Center;
  49.              pen.Width = 1;
  50.             switch (lineStyle)
  51.             {
  52.                 case DataDynamics.ActiveReports.BorderLineStyle.Dash:
  53.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
  54.                    
  55.                     break;
  56.                 case DataDynamics.ActiveReports.BorderLineStyle.DashDot:
  57.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
  58.                    
  59.                     break;
  60.                 case DataDynamics.ActiveReports.BorderLineStyle.DashDotDot:
  61.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot;
  62.                   
  63.                     break;
  64.                 case DataDynamics.ActiveReports.BorderLineStyle.Dot:
  65.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
  66.                  
  67.                     break;
  68.                 case DataDynamics.ActiveReports.BorderLineStyle.Double://需要绘制两次
  69.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
  70.                     pen.Width = 1;
  71.                     break;
  72.                 case DataDynamics.ActiveReports.BorderLineStyle.ExtraThickSolid:
  73.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
  74.                     pen.Width = 4;
  75.                     break;
  76.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDash:
  77.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
  78.                     pen.Width = 2;
  79.                    
  80.                     break;
  81.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDashDot:
  82.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
  83.                     pen.Width = 2;
  84.                     break;
  85.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDashDotDot:
  86.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot;
  87.                     pen.Width = 2;
  88.                     break;
  89.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDot:
  90.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
  91.                     pen.Width = 2;
  92.                     break;
  93.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDouble:
  94.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
  95.                     pen.Width = 2;
  96.                     break;
  97.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickSolid:
  98.                     pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
  99.                     pen.Width = 2;
  100.                     break;
  101.                 default:
  102.                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
  103.                    
  104.                     break;
  105.             }
  106.             return pen;
  107.         }
  108.         protected string GetBorderLineStyleStr(DataDynamics.ActiveReports.BorderLineStyle lineStyle)
  109.         {
  110.             string result = string.Empty;
  111.             switch (lineStyle)
  112.             {
  113.                 case DataDynamics.ActiveReports.BorderLineStyle.Dash:
  114.                     result = "虚线";
  115.                     break;
  116.                 case DataDynamics.ActiveReports.BorderLineStyle.DashDot:
  117.                     result = "划线 + 点";
  118.                     break;
  119.                 case DataDynamics.ActiveReports.BorderLineStyle.DashDotDot:
  120.                     result = "划线 + 点 + 点";
  121.                     break;
  122.                 case DataDynamics.ActiveReports.BorderLineStyle.Dot:
  123.                     result = "点";
  124.                     break;
  125.                 case DataDynamics.ActiveReports.BorderLineStyle.Double:
  126.                     result = "双实线";
  127.                     break;
  128.                 case DataDynamics.ActiveReports.BorderLineStyle.ExtraThickSolid:
  129.                     result = "加粗实线";
  130.                     break;
  131.                 case DataDynamics.ActiveReports.BorderLineStyle.Solid:
  132.                     result = "实线";
  133.                     break;
  134.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDash:
  135.                     result = "粗虚线";
  136.                     break;
  137.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDashDot:
  138.                     result = "粗的划线 + 点";
  139.                     break;
  140.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDashDotDot:
  141.                     result = "粗的划线 + 点 + 点";
  142.                     break;
  143.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDot:
  144.                     result = "粗点";
  145.                     break;
  146.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickDouble:
  147.                     result = "粗的双实线";
  148.                     break;
  149.                 case DataDynamics.ActiveReports.BorderLineStyle.ThickSolid:
  150.                     result = "粗实线";
  151.                     break;
  152.                 default:
  153.                     result= "无边框";
  154.                     break;
  155.             }
  156.             return string.Format("{0}({1})", result, lineStyle);
  157.         }
绘制边框颜色块:


  1.  protected override void OnCreateGalleryItems()
  2.         {
  3.             base.OnCreateGalleryItems();
  4.             //********************************************************自定义颜色
  5.         
  6.             Color[] colors = CellColors;
  7.             foreach (Color clr in colors)
  8.             {
  9.                 CreateColorToImage(0, clr);
  10.             }
  11.             this.RibbonGallery.Gallery.Groups[0].Items[0].Checked = true;
  12.             //********************************************************Web 颜色
  13.             foreach (Color clr in DevExpress.XtraEditors.Popup.ColorListBoxViewInfo.WebColors)
  14.             {
  15.                 if (clr == Color.Transparent) continue;
  16.                 
  17.                 CreateColorToImage(1, clr);
  18.             }

  19.             //string[] kcs = System.Enum.GetNames(typeof(System.Drawing.KnownColor));

  20.             //foreach (string clrName in kcs)
  21.             //{
  22.             //    Color clr = Color.FromName(clrName);
  23.             //    CreateColorToImage(1, clr);
  24.             //}
  25.             //********************************************************系统颜色
  26.             foreach (Color clr in DevExpress.XtraEditors.Popup.ColorListBoxViewInfo.SystemColors)
  27.             {
  28.                 CreateColorToImage(2, clr);
  29.             }
  30.         }

  31.         private GalleryItem CreateColorToImage(int groupIndex, Color clr)
  32.         { return CreateColorToImage(groupIndex, clr, false); }

  33.         private GalleryItem CreateColorToImage(int groupIndex, Color clr, bool checkedTrue)
  34.         {
  35.             GalleryItem gItem = new GalleryItem();

  36.             gItem.Caption = clr.Name;
  37.             gItem.Tag = clr;
  38.             gItem.Hint = gItem.Caption;
  39.             Bitmap image = new Bitmap(16, 16);

  40.             using (Graphics g = Graphics.FromImage(image))
  41.             {
  42.                 SolidBrush brush = new SolidBrush(clr);
  43.                 using (brush)
  44.                 {
  45.                     g.FillRectangle(brush, 0, 0, image.Width, image.Height);
  46.                     if (clr == Color.Transparent)
  47.                     {
  48.                         StringFormat sf = new StringFormat();
  49.                         sf.Alignment = StringAlignment.Center;
  50.                         sf.LineAlignment = StringAlignment.Center;
  51.                         SolidBrush sb = new SolidBrush(Color.Black);
  52.                         using (sb)
  53.                         {
  54.                             g.DrawString("T"this.RibbonGallery.Font, sb, new Rectangle(0, 0, image.Width, image.Height), sf);
  55.                             sf.Dispose();
  56.                         }
  57.                     }
  58.                 }

  59.             }
  60.             gItem.Image = image;
  61.             if (checkedTrue) gItem.Checked = true;

  62.             RibbonGallery.Gallery.Groups[groupIndex].Items.Add(gItem);

  63.             return gItem;
  64.         }
丰富的打印设置:
相关设置捷径:


相关代码:
基类:
  1. public abstract class PageGalleryDropDownBase : GalleryDropDown
  2.     {
  3.         private ReportDesignerRibbonForm owner = null;
  4.         private BarButtonItem parentItem = null;
  5.         protected DataDynamics.ActiveReports.PageSettings m_pageSettings=null;
  6.         GalleryItemGroup group = new GalleryItemGroup();
  7.         protected abstract PageGalleryItem[] Items { get; }
  8.         protected virtual int RowCount { get { return group.Items.Count; } }
  9.         /// <summary>
  10.         /// 如果定义为-1,则为项目数目不确定
  11.         /// </summary>
  12.         protected abstract int CreateItemsCount { get; }
  13.         public enum CommandsCategory
  14.         {
  15.             /// <summary>
  16.             /// 空命令
  17.             /// </summary>
  18.             None = 0,
  19.             /// <summary>
  20.             /// 页边距设置
  21.             /// </summary>
  22.             PageMargins,
  23.             /// <summary>
  24.             /// 纸张方向设置
  25.             /// </summary>
  26.             PageOrientation,
  27.             /// <summary>
  28.             /// 纸张大小设置
  29.             /// </summary>
  30.             PaperSize,
  31.             /// <summary>
  32.             /// 打印纸张来源设置
  33.             /// </summary>
  34.             PaperSources,
  35.             /// <summary>
  36.             /// 逐份打印设置
  37.             /// </summary>
  38.             PrintCollate,
  39.             /// <summary>
  40.             /// 双面打印设置
  41.             /// </summary>
  42.             PrintDuplex,
  43.             /// <summary>
  44.             /// 设置打印机
  45.             /// </summary>
  46.             Printer,
  47.         }
  48.         protected Image GetImageFromResource(string resourceName) { return Utils.GetImage(resourceName); }
  49.         protected PageGalleryDropDownBase(ReportDesignerRibbonForm owner, BarButtonItem parentItem)
  50.         {
  51.             this.owner = owner;
  52.             this.m_pageSettings = owner.Report.PageSettings;
  53.             this.parentItem = parentItem;
  54.             this.parentItem.DropDownControl = this;
  55.             if (this.parentItem.ButtonStyle != BarButtonStyle.DropDown) this.parentItem.ButtonStyle = BarButtonStyle.DropDown;
  56.             this.Ribbon = owner.Ribbon;
  57.             this.OnInitGallery();
  58.         }
  59.         protected virtual void OnInitGallery()
  60.         {
  61.             Gallery.Appearance.ItemCaption.TextOptions.HAlignment = HorzAlignment.Near;
  62.             Gallery.Appearance.ItemCaption.Options.UseTextOptions = true;
  63.             Gallery.Appearance.ItemDescription.TextOptions.HAlignment = HorzAlignment.Near;
  64.             Gallery.Appearance.ItemDescription.Options.UseTextOptions = true;
  65.             Gallery.ColumnCount = 1;
  66.             Gallery.ShowGroupCaption = false;
  67.             Gallery.ShowItemText = true;
  68.             Gallery.DrawImageBackground = false;
  69.             Gallery.Groups.Add(group);
  70.             GalleryItemClick += new GalleryItemClickEventHandler(OnGalleryItemClick);
  71.         }
  72.         /// <summary>
  73.         /// 更新列表项目(如:当设计单位更改后...)
  74.         /// </summary>
  75.         public virtual void Update() { createdFlag = false; m_pageSettings = this.Designer.Report.PageSettings; }
  76.         /// <summary>
  77.         /// 更新父按钮的工具提示
  78.         /// </summary>
  79.         public virtual void UpdateParentItemHint() { }
  80.         private bool createdFlag = false;
  81.         protected virtual bool CanBeforePopupClear { get { return true; } }
  82.         protected override void OnBeforePopup(CancelEventArgs e)
  83.         {
  84.             base.OnBeforePopup(e);
  85.             BeginUpdate();
  86.             if (createdFlag == false || CanBeforePopupClear) group.Items.Clear();
  87.             bool checkedFlag = false;
  88.             foreach (PageGalleryItem item in Items)
  89.             {
  90.                 item.Checked = false;
  91.                 if (createdFlag == false || CanBeforePopupClear) group.Items.Add(item);
  92.                 bool flag = IsItemChecked(item);
  93.                 if (checkedFlag == false) item.Checked = flag;
  94.                 if (flag == true) checkedFlag = true;
  95.             }
  96.             Gallery.RowCount = RowCount;
  97.             EndUpdate();
  98.             createdFlag = true;
  99.         }
  100.         #region Properties
  101.         public DataDynamics.ActiveReports.Design.Designer Designer { get { return Owner.Designer; } }
  102.         public ReportDesignerRibbonForm Owner { get { return owner; } }
  103.         public BarButtonItem ParentItem { get { return parentItem; } }
  104.         /// <summary>
  105.         /// 获取已勾选的项
  106.         /// </summary>
  107.         public PageGalleryItem GetCheckedItem
  108.         {
  109.             get
  110.             {
  111.                 foreach (GalleryItemGroup group in this.Gallery.Groups)
  112.                 {
  113.                     foreach (PageGalleryItem gItem in group.Items)
  114.                     {
  115.                         if (gItem.Checked) return gItem;
  116.                     }
  117.                 }
  118.                 return null;
  119.             }
  120.         }
  121.         /// <summary>
  122.         /// 获取打印机页面设置
  123.         /// </summary>
  124.         public DataDynamics.ActiveReports.PageSettings PageSettings { get { return m_pageSettings; } }
  125.         protected virtual bool IsItemChecked(PageGalleryItem item)
  126.         {
  127.             return false;
  128.         }
  129.         /// <summary>
  130.         /// 获取是否为公制单位(cm)
  131.         /// </summary>
  132.         public bool IsMetric
  133.         {
  134.             get { return this.Owner.Designer.DesignUnits == DataDynamics.ActiveReports.Design.MeasurementUnits.Metric; }
  135.         }
  136.         #endregion
  137.         protected override void Dispose(bool disposing)
  138.         {
  139.             try
  140.             {
  141.                 if (disposing)
  142.                 {
  143.                     GalleryItemClick -= new GalleryItemClickEventHandler(OnGalleryItemClick);
  144.                 }
  145.             }
  146.             finally
  147.             {
  148.                 base.Dispose(disposing);
  149.             }
  150.         }
  151.         void OnGalleryItemClick(object sender, GalleryItemClickEventArgs e)
  152.         {
  153.             if (e.Item.Checked) return;
  154.             PageGalleryItem commandItem = e.Item as PageGalleryItem;
  155.             OnGalleryItemClick(commandItem);
  156.         }
  157.         protected virtual void OnGalleryItemClick(PageGalleryItem commandItem)
  158.         {
  159.             this.Owner.DesignChanged = true;
  160.         }
  161.     }
  1.  public abstract class PageGalleryDropDown : PageGalleryDropDownBase
  2.     {
  3.         protected PageGalleryItem[] items = null;
  4.         private CommandsCategory command = CommandsCategory.None;
  5.         protected object[] args = null;
  6.         protected PageGalleryDropDown(ReportDesignerRibbonForm owner,BarButtonItem parentItem, CommandsCategory command)
  7.             : base(owner,parentItem)
  8.         {
  9.             this.command = command;
  10.         }
  11.         protected PageGalleryDropDown(ReportDesignerRibbonForm owner, BarButtonItem parentItem, CommandsCategory command, object[] args)
  12.             : base(owner,parentItem)
  13.         {  
  14.             this.command = command;
  15.             this.args = args;
  16.           
  17.         }
  18.         public override void Update()
  19.         {
  20.             base.Update();
  21.             items = null;
  22.             args = null;
  23.         }
  24.         protected override PageGalleryItem[] Items
  25.         {
  26.             get
  27.             {//如果ItemsCount==-1,则需要重写
  28.                 if (items == null) CreateItems();
  29.                 return items;
  30.             }
  31.         }
  32.         /// <summary>
  33.         /// 获取所属的命令集
  34.         /// </summary>
  35.         protected CommandsCategory Command { get { return command; } }
  36.         protected virtual object[] Args {
  37.             get { return args; }
  38.             set { args = value; }
  39.         }
  40.         protected virtual void CreateItems() {
  41.             items = new PageGalleryItem[this.CreateItemsCount];
  42.             for (int i = 0; i < this.CreateItemsCount; i++)
  43.                 items[i] = CreateGalleryItem(args[i]);//args为子命令枚举成员
  44.         }
  45.         protected System.Drawing.Printing.PrinterSettings CreatePrinterSettings()
  46.         {
  47.             System.Drawing.Printing.PrinterSettings ps = new PrinterSettings();
  48.             ps.PrinterName = this.Designer.Report.Document != null ? this.Designer.Report.Document.Printer.PrinterName : ps.DefaultPageSettings.PrinterSettings.PrinterName;
  49.             return ps;
  50.         }
  51.         /// <summary>
  52.         /// 创建页面设置相关的下拉项目
  53.         /// </summary>
  54.         /// <param name="arg">子命令枚举成员</param>
  55.         /// <returns></returns>
  56.         protected virtual PageGalleryItem CreateGalleryItem(object arg) { return null; }
  57.     }
举例打印机设置:
  1. public class PrinterGalleryDropDow : PageGalleryDropDown
  2.     {
  3.         public event EventHandler PrinterChanged = null;
  4.         public PrinterGalleryDropDow(ReportDesignerRibbonForm owner, BarButtonItem item)
  5.             : base(owner, item, CommandsCategory.Printer)
  6.         {
  7.             Gallery.ImageSize = new Size(48, 48);
  8.         }
  9.         static string GetPrinterDescription(string printerName)
  10.         {
  11.             return IsNetPrinter(printerName) ? "网络打印机" : "本地打印机";
  12.         }
  13.         static bool IsNetPrinter(string printerName)
  14.         {
  15.            return printerName.IndexOf(@"/") > -1;
  16.         }
  17.         const int MaxPrinterGalleryRowCount = 7;
  18.         protected override int CreateItemsCount { get { return -1; } }
  19.         protected override bool CanBeforePopupClear { get { return false; } }
  20.         public string GetDefaultPrinter
  21.         {
  22.             get
  23.             {
  24.                 string defaultPrinter = string.Empty;
  25.                 if (this.Designer.Report.Document != null)
  26.                     defaultPrinter = this.Designer.Report.Document.Printer.PrinterName;
  27.                 else
  28.                 {
  29.                     PrinterSettings ps = new PrinterSettings();
  30.                     defaultPrinter = ps.DefaultPageSettings.PrinterSettings.PrinterName;
  31.                 }
  32.                 return defaultPrinter;
  33.             }
  34.         }
  35.         public override void Update()
  36.         {
  37.             base.Update();
  38.             this.CreateItems();
  39.             this.SetPrinter(GetDefaultPrinter);
  40.         }
  41.         protected override void CreateItems()
  42.         {
  43.             List<PageGalleryItem> itemsAll = new List<PageGalleryItem>();
  44.             Image imageLocal = global::CIMS.Report.Designer.ReportDesignerResources.LocalPrinter;
  45.             Image imageNet = global::CIMS.Report.Designer.ReportDesignerResources.NetPrinter;
  46.             string defaultPrinter = GetDefaultPrinter;
  47.             foreach (string printerName in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
  48.             {
  49.                 PageGalleryItem item = new PageGalleryItem(IsNetPrinter(printerName) ? imageNet : imageLocal,"打印到 "+ printerName, GetPrinterDescription(printerName), printerName);
  50.                 if (printerName == defaultPrinter) item.Checked = true;
  51.                 itemsAll.Add(item);
  52.             }
  53.             
  54.             items = new PageGalleryItem[itemsAll.Count];
  55.             itemsAll.CopyTo(items, 0);
  56.         }
  57.         public override void UpdateParentItemHint()
  58.         {
  59.             this.UpdateParentItemHint(this.GetDefaultPrinter);
  60.         }
  61.         public void UpdateParentItemHint(string printerName)
  62.         {
  63.             string title = string.Empty;
  64.             foreach (PageGalleryItem item in Items)
  65.             {
  66.                 if (IsItemChecked(item))
  67.                 {
  68.                     title = item.Caption;
  69.                     break;
  70.                 }
  71.             }
  72.             this.ParentItem.Hint = title + "/n" + GetPrinterDescription(printerName);
  73.         }
  74.         protected override int RowCount { get { return Math.Min(MaxPrinterGalleryRowCount, base.RowCount); } }
  75.         protected override bool IsItemChecked(PageGalleryItem item)
  76.         {
  77.             if (this.Designer.Report.Document == null)
  78.             {
  79.                 //默认
  80.                 return false;
  81.             }
  82.             string printerName = item.CommandParameter.ToString();
  83.             return Designer.Report.Document.Printer.PrinterName == item.CommandParameter.ToString();
  84.             //return PageSettings.PaperName == paperSize.PaperName || (PageSettings.PaperWidth == paperSize.Width/100 && PageSettings.PaperHeight == paperSize.Height/100);
  85.         }
  86.         protected override void OnGalleryItemClick(PageGalleryItem commandItem)
  87.         {
  88.             base.OnGalleryItemClick(commandItem);
  89.             if (this.Designer.Report.Document == null)
  90.             {
  91.                 System.Windows.Forms.MessageBox.Show("当前报表设计还没有创建Document对象!""设置打印机", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
  92.                 return;
  93.             }
  94.             string printerName = commandItem.CommandParameter.ToString();
  95.             this.SetPrinter(printerName);
  96.         }
  97.         protected void SetPrinter(string printerName)
  98.         {
  99.             if (Designer.Report.Document.Printer.PrinterName == printerName) return;
  100.             this.Designer.Report.Document.Printer.PrinterName = printerName;
  101.             this.UpdateParentItemHint(printerName);
  102.             if (PrinterChanged != null) PrinterChanged(this, EventArgs.Empty);
  103.         }

完.

猜你喜欢

转载自blog.csdn.net/3tzjq/article/details/3255467