WpfDesignerControl.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. using FastReport.Design.StandardDesigner;
  2. using FastReport.Utils;
  3. using System;
  4. using System.ComponentModel;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. namespace FastReport.Design
  8. {
  9. /// <summary>
  10. /// Represents the standard report designer.
  11. /// </summary>
  12. public partial class WpfDesignerControl : UserControl
  13. {
  14. #region Properties
  15. /// <summary>
  16. /// Gets inner designer control.
  17. /// </summary>
  18. public DesignerControl InnerDesigner { get; }
  19. /// <summary>
  20. /// Gets or sets the edited report.
  21. /// </summary>
  22. /// <remarks>
  23. /// To initialize the designer, you need to pass a Report instance to this property.
  24. /// This will create the designer's surface associated with the report.
  25. /// </remarks>
  26. public Report Report
  27. {
  28. get => InnerDesigner.Report;
  29. set => InnerDesigner.Report = value;
  30. }
  31. /// <summary>
  32. /// Gets or sets the visual style.
  33. /// </summary>
  34. public UIStyle UIStyle
  35. {
  36. get => InnerDesigner.UIStyle;
  37. set => InnerDesigner.UIStyle = value;
  38. }
  39. /// <summary>
  40. /// Gets or sets a value indicating whether the main menu should be displayed or not.
  41. /// </summary>
  42. public bool ShowMainMenu
  43. {
  44. get => InnerDesigner.ShowMainMenu;
  45. set => InnerDesigner.ShowMainMenu = value;
  46. }
  47. /// <summary>
  48. /// Gets or sets a value indicating whether the status bar should be displayed or not.
  49. /// </summary>
  50. public bool ShowStatusBar
  51. {
  52. get => InnerDesigner.ShowStatusBar;
  53. set => InnerDesigner.ShowStatusBar = value;
  54. }
  55. /// <summary>
  56. /// Gets or sets the zoom factor.
  57. /// </summary>
  58. public float Zoom
  59. {
  60. get => InnerDesigner.Zoom;
  61. set => InnerDesigner.Zoom = value;
  62. }
  63. /// <summary>
  64. /// Gets or sets the layout state of the designer.
  65. /// </summary>
  66. /// <remarks>
  67. /// You may use this property to save and restore the designer's layout in your code. However, consider using the
  68. /// <see cref="SaveConfig()"/> and <see cref="RestoreConfig()"/> methods that use FastReport configuration file.
  69. /// </remarks>
  70. public string LayoutState
  71. {
  72. get => InnerDesigner.LayoutState;
  73. set => InnerDesigner.LayoutState = value;
  74. }
  75. /// <summary>
  76. /// Gets or sets a value that determines whether the control should handle the window's Closing event.
  77. /// </summary>
  78. public bool HandleWindowEvents { get; set; } = true;
  79. /// <summary>
  80. /// Occurs when the designer's UI state is changed.
  81. /// </summary>
  82. /// <remarks>
  83. /// Use this event to update state of your own controls bound to the designer's commands.
  84. /// </remarks>
  85. public event EventHandler UIStateChanged
  86. {
  87. add => InnerDesigner.UIStateChanged += value;
  88. remove => InnerDesigner.UIStateChanged -= value;
  89. }
  90. #endregion
  91. #region Commands
  92. public DesignerCommand cmdNew { get; }
  93. public DesignerCommand cmdNewPage { get; }
  94. public DesignerCommand cmdNewDialog { get; }
  95. public OpenCommand cmdOpen { get; }
  96. public DesignerCommand cmdOpenPage { get; }
  97. public DesignerCommand cmdOpenViaCloud { get; }
  98. public DesignerCommand cmdSave { get; }
  99. public DesignerCommand cmdSaveToCloud { get; }
  100. public DesignerCommand cmdSaveAs { get; }
  101. public DesignerCommand cmdSaveWithRandomData { get; }
  102. public DesignerCommand cmdSaveAll { get; }
  103. public DesignerCommand cmdClose { get; }
  104. public DesignerCommand cmdCloseAll { get; }
  105. public DesignerCommand cmdPreview { get; }
  106. public DesignerCommand cmdPreviewCloud { get; }
  107. public DesignerCommand cmdPrinterSetup { get; }
  108. public DesignerCommand cmdPageSetup { get; }
  109. public DesignerCommand cmdAddData { get; }
  110. public DesignerCommand cmdSortDataSources { get; }
  111. public DesignerCommand cmdChooseData { get; }
  112. public DesignerCommand cmdUndo { get; }
  113. public DesignerCommand cmdRedo { get; }
  114. public DesignerCommand cmdCut { get; }
  115. public DesignerCommand cmdCopy { get; }
  116. public DesignerCommand cmdPaste { get; }
  117. public DesignerCommand cmdFormatPainter { get; }
  118. public DesignerCommand cmdDelete { get; }
  119. public DesignerCommand cmdCopyPage { get; }
  120. public DesignerCommand cmdDeletePage { get; }
  121. public DesignerCommand cmdSelectAll { get; }
  122. public DesignerCommand cmdGroup { get; }
  123. public DesignerCommand cmdUngroup { get; }
  124. public DesignerCommand cmdEdit { get; }
  125. public DesignerCommand cmdFind { get; }
  126. public DesignerCommand cmdReplace { get; }
  127. public DesignerCommand cmdBringToFront { get; }
  128. public DesignerCommand cmdSendToBack { get; }
  129. public DesignerCommand cmdInsert { get; }
  130. public DesignerCommand cmdInsertBand { get; }
  131. public RecentFilesCommand cmdRecentFiles { get; }
  132. public DesignerCommand cmdSelectLanguage { get; }
  133. public DesignerCommand cmdViewStartPage { get; }
  134. public DesignerCommand cmdReportSettings { get; }
  135. public DesignerCommand cmdOptions { get; }
  136. public DesignerCommand cmdReportStyles { get; }
  137. public DesignerCommand cmdReportValidation { get; }
  138. public DesignerCommand cmdHelpContents { get; }
  139. public DesignerCommand cmdAccount { get; }
  140. public DesignerCommand cmdAbout { get; }
  141. public DesignerCommand cmdPolySelectMove { get; }
  142. public DesignerCommand cmdPolySelectPointer { get; }
  143. public DesignerCommand cmdPolySelectAddPoint { get; }
  144. public DesignerCommand cmdPolySelectBezier { get; }
  145. public DesignerCommand cmdPolySelectRemovePoint { get; }
  146. #endregion
  147. #region Methods
  148. /// <summary>
  149. /// Saves config to a FastReport configuration file.
  150. /// </summary>
  151. public void SaveConfig() => InnerDesigner.SaveConfig();
  152. /// <summary>
  153. /// Restores config from a FastReport configuration file.
  154. /// </summary>
  155. /// <remarks>
  156. /// Call this method to restore the designer's layout. You need to do this after the
  157. /// designer's control is placed on a form.
  158. /// </remarks>
  159. public void RestoreConfig() => InnerDesigner.RestoreConfig();
  160. /// <summary>
  161. /// AutoSave system initialization.
  162. /// </summary>
  163. public void StartAutoSave() => InnerDesigner.StartAutoSave();
  164. /// <summary>
  165. /// Stops the AutoSave system.
  166. /// </summary>
  167. public void StopAutoSave() => InnerDesigner.StopAutoSave();
  168. /// <summary>
  169. /// Checks if parent window can be closed.
  170. /// </summary>
  171. /// <param name="e">The cancel event args.</param>
  172. /// <remarks>
  173. /// Use this method in the window's Closing event handler if you set <see cref="HandleWindowEvents"/> to false.
  174. /// This method checks if the embedded preview is running and cancels it. Also if there is unsaved changes, the user will be asked to save changes.
  175. /// </remarks>
  176. public void ParentWindowClosing(CancelEventArgs e)
  177. {
  178. var args = new System.Windows.Forms.FormClosingEventArgs(System.Windows.Forms.CloseReason.UserClosing, false);
  179. InnerDesigner.ParentFormClosing(args);
  180. e.Cancel = args.Cancel;
  181. }
  182. #endregion
  183. private DesignerCommand CreateCmd(FastReport.Design.DesignerCommand innerCommand) => new DesignerCommand(this, innerCommand);
  184. /// <summary>
  185. /// Initializes a new instance of the <see cref="WpfDesignerControl"/> class.
  186. /// </summary>
  187. public WpfDesignerControl()
  188. {
  189. InnerDesigner = new DesignerControl();
  190. var control = InnerDesigner.control;
  191. control.Width = double.NaN;
  192. control.Height = double.NaN;
  193. control.HorizontalAlignment = HorizontalAlignment.Stretch;
  194. control.VerticalAlignment = VerticalAlignment.Stretch;
  195. Content = control;
  196. UseLayoutRounding = true;
  197. Loaded += (s, e) =>
  198. {
  199. var window = Window.GetWindow(this);
  200. if (window == null)
  201. return;
  202. System.Windows.Forms.DpiRescaler.Install(window, InnerDesigner, this, (s, e) => InnerDesigner.UpdateDpiDependencies(null));
  203. // update toolbar area
  204. InnerDesigner.UpdateUIStyle();
  205. // WPF bug: designer workspace is not initialized if the dialog form is the first page in a report (reason: visible designer form is needed)
  206. InnerDesigner.UpdateFirstDialogPage();
  207. // handle parent window events
  208. if (HandleWindowEvents)
  209. {
  210. RestoreConfig();
  211. StartAutoSave();
  212. window.Closing += (s, e) =>
  213. {
  214. ParentWindowClosing(e);
  215. if (!e.Cancel)
  216. {
  217. SaveConfig();
  218. StopAutoSave();
  219. }
  220. };
  221. }
  222. };
  223. cmdNew = CreateCmd(InnerDesigner.cmdNew);
  224. cmdNewPage = CreateCmd(InnerDesigner.cmdNewPage);
  225. cmdNewDialog = CreateCmd(InnerDesigner.cmdNewDialog);
  226. cmdOpen = new OpenCommand(this, InnerDesigner.cmdOpen);
  227. cmdOpenPage = CreateCmd(InnerDesigner.cmdOpenPage);
  228. cmdOpenViaCloud = CreateCmd(InnerDesigner.cmdOpenViaCloud);
  229. cmdSave = CreateCmd(InnerDesigner.cmdSave);
  230. cmdSaveToCloud = CreateCmd(InnerDesigner.cmdSaveToCloudCommand);
  231. cmdSaveAs = CreateCmd(InnerDesigner.cmdSaveAs);
  232. cmdSaveWithRandomData = CreateCmd(InnerDesigner.cmdSaveWithRandomData);
  233. cmdSaveAll = CreateCmd(InnerDesigner.cmdSaveAll);
  234. cmdClose = CreateCmd(InnerDesigner.cmdClose);
  235. cmdCloseAll = CreateCmd(InnerDesigner.cmdCloseAll);
  236. cmdPreview = CreateCmd(InnerDesigner.cmdPreview);
  237. cmdPreviewCloud = CreateCmd(InnerDesigner.cmdPreviewCloud);
  238. cmdPrinterSetup = CreateCmd(InnerDesigner.cmdPrinterSetup);
  239. cmdPageSetup = CreateCmd(InnerDesigner.cmdPageSetup);
  240. cmdAddData = CreateCmd(InnerDesigner.cmdAddData);
  241. cmdSortDataSources = CreateCmd(InnerDesigner.cmdSortDataSources);
  242. cmdChooseData = CreateCmd(InnerDesigner.cmdChooseData);
  243. cmdUndo = CreateCmd(InnerDesigner.cmdUndo);
  244. cmdRedo = CreateCmd(InnerDesigner.cmdRedo);
  245. cmdCut = CreateCmd(InnerDesigner.cmdCut);
  246. cmdCopy = CreateCmd(InnerDesigner.cmdCopy);
  247. cmdPaste = CreateCmd(InnerDesigner.cmdPaste);
  248. cmdFormatPainter = CreateCmd(InnerDesigner.cmdFormatPainter);
  249. cmdDelete = CreateCmd(InnerDesigner.cmdDelete);
  250. cmdCopyPage = CreateCmd(InnerDesigner.cmdCopyPage);
  251. cmdDeletePage = CreateCmd(InnerDesigner.cmdDeletePage);
  252. cmdSelectAll = CreateCmd(InnerDesigner.cmdSelectAll);
  253. cmdGroup = CreateCmd(InnerDesigner.cmdGroup);
  254. cmdUngroup = CreateCmd(InnerDesigner.cmdUngroup);
  255. cmdEdit = CreateCmd(InnerDesigner.cmdEdit);
  256. cmdFind = CreateCmd(InnerDesigner.cmdFind);
  257. cmdReplace = CreateCmd(InnerDesigner.cmdReplace);
  258. cmdBringToFront = CreateCmd(InnerDesigner.cmdBringToFront);
  259. cmdSendToBack = CreateCmd(InnerDesigner.cmdSendToBack);
  260. cmdInsert = CreateCmd(InnerDesigner.cmdInsert);
  261. cmdInsertBand = CreateCmd(InnerDesigner.cmdInsertBand);
  262. cmdRecentFiles = new RecentFilesCommand(this, InnerDesigner.cmdRecentFiles);
  263. cmdSelectLanguage = CreateCmd(InnerDesigner.cmdSelectLanguage);
  264. cmdViewStartPage = CreateCmd(InnerDesigner.cmdViewStartPage);
  265. cmdReportSettings = CreateCmd(InnerDesigner.cmdReportSettings);
  266. cmdOptions = CreateCmd(InnerDesigner.cmdOptions);
  267. cmdReportStyles = CreateCmd(InnerDesigner.cmdReportStyles);
  268. cmdReportValidation = CreateCmd(InnerDesigner.cmdReportValidation);
  269. cmdHelpContents = CreateCmd(InnerDesigner.cmdHelpContents);
  270. cmdAccount = CreateCmd(InnerDesigner.cmdAccount);
  271. cmdAbout = CreateCmd(InnerDesigner.cmdAbout);
  272. cmdPolySelectMove = CreateCmd(InnerDesigner.CmdPolySelectMove);
  273. cmdPolySelectPointer = CreateCmd(InnerDesigner.CmdPolySelectPointer);
  274. cmdPolySelectAddPoint = CreateCmd(InnerDesigner.CmdPolySelectAddPoint);
  275. cmdPolySelectBezier = CreateCmd(InnerDesigner.CmdPolySelectBezier);
  276. cmdPolySelectRemovePoint = CreateCmd(InnerDesigner.CmdPolySelectRemovePoint);
  277. }
  278. }
  279. }