WpfDesignerControl.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  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. if (e.Cancel)
  179. return;
  180. var args = new System.Windows.Forms.FormClosingEventArgs(System.Windows.Forms.CloseReason.UserClosing, false);
  181. InnerDesigner.ParentFormClosing(args);
  182. e.Cancel = args.Cancel;
  183. }
  184. #endregion
  185. private DesignerCommand CreateCmd(FastReport.Design.DesignerCommand innerCommand) => new DesignerCommand(this, innerCommand);
  186. /// <summary>
  187. /// Initializes a new instance of the <see cref="WpfDesignerControl"/> class.
  188. /// </summary>
  189. public WpfDesignerControl()
  190. {
  191. InnerDesigner = new DesignerControl();
  192. var control = InnerDesigner.control;
  193. control.Width = double.NaN;
  194. control.Height = double.NaN;
  195. control.HorizontalAlignment = HorizontalAlignment.Stretch;
  196. control.VerticalAlignment = VerticalAlignment.Stretch;
  197. Content = control;
  198. UseLayoutRounding = true;
  199. Loaded += (s, e) =>
  200. {
  201. var window = Window.GetWindow(this);
  202. if (window == null)
  203. return;
  204. System.Windows.Forms.DpiRescaler.Install(window, InnerDesigner, this, (s, e) => InnerDesigner.UpdateDpiDependencies(null));
  205. // update toolbar area
  206. InnerDesigner.UpdateUIStyle();
  207. // WPF bug: designer workspace is not initialized if the dialog form is the first page in a report (reason: visible designer form is needed)
  208. InnerDesigner.UpdateFirstDialogPage();
  209. // handle parent window events
  210. if (HandleWindowEvents)
  211. {
  212. RestoreConfig();
  213. StartAutoSave();
  214. window.Closing += (s, e) =>
  215. {
  216. ParentWindowClosing(e);
  217. if (!e.Cancel)
  218. {
  219. SaveConfig();
  220. StopAutoSave();
  221. }
  222. };
  223. }
  224. };
  225. cmdNew = CreateCmd(InnerDesigner.cmdNew);
  226. cmdNewPage = CreateCmd(InnerDesigner.cmdNewPage);
  227. cmdNewDialog = CreateCmd(InnerDesigner.cmdNewDialog);
  228. cmdOpen = new OpenCommand(this, InnerDesigner.cmdOpen);
  229. cmdOpenPage = CreateCmd(InnerDesigner.cmdOpenPage);
  230. cmdOpenViaCloud = CreateCmd(InnerDesigner.cmdOpenViaCloud);
  231. cmdSave = CreateCmd(InnerDesigner.cmdSave);
  232. cmdSaveToCloud = CreateCmd(InnerDesigner.cmdSaveToCloudCommand);
  233. cmdSaveAs = CreateCmd(InnerDesigner.cmdSaveAs);
  234. cmdSaveWithRandomData = CreateCmd(InnerDesigner.cmdSaveWithRandomData);
  235. cmdSaveAll = CreateCmd(InnerDesigner.cmdSaveAll);
  236. cmdClose = CreateCmd(InnerDesigner.cmdClose);
  237. cmdCloseAll = CreateCmd(InnerDesigner.cmdCloseAll);
  238. cmdPreview = CreateCmd(InnerDesigner.cmdPreview);
  239. cmdPreviewCloud = CreateCmd(InnerDesigner.cmdPreviewCloud);
  240. cmdPrinterSetup = CreateCmd(InnerDesigner.cmdPrinterSetup);
  241. cmdPageSetup = CreateCmd(InnerDesigner.cmdPageSetup);
  242. cmdAddData = CreateCmd(InnerDesigner.cmdAddData);
  243. cmdSortDataSources = CreateCmd(InnerDesigner.cmdSortDataSources);
  244. cmdChooseData = CreateCmd(InnerDesigner.cmdChooseData);
  245. cmdUndo = CreateCmd(InnerDesigner.cmdUndo);
  246. cmdRedo = CreateCmd(InnerDesigner.cmdRedo);
  247. cmdCut = CreateCmd(InnerDesigner.cmdCut);
  248. cmdCopy = CreateCmd(InnerDesigner.cmdCopy);
  249. cmdPaste = CreateCmd(InnerDesigner.cmdPaste);
  250. cmdFormatPainter = CreateCmd(InnerDesigner.cmdFormatPainter);
  251. cmdDelete = CreateCmd(InnerDesigner.cmdDelete);
  252. cmdCopyPage = CreateCmd(InnerDesigner.cmdCopyPage);
  253. cmdDeletePage = CreateCmd(InnerDesigner.cmdDeletePage);
  254. cmdSelectAll = CreateCmd(InnerDesigner.cmdSelectAll);
  255. cmdGroup = CreateCmd(InnerDesigner.cmdGroup);
  256. cmdUngroup = CreateCmd(InnerDesigner.cmdUngroup);
  257. cmdEdit = CreateCmd(InnerDesigner.cmdEdit);
  258. cmdFind = CreateCmd(InnerDesigner.cmdFind);
  259. cmdReplace = CreateCmd(InnerDesigner.cmdReplace);
  260. cmdBringToFront = CreateCmd(InnerDesigner.cmdBringToFront);
  261. cmdSendToBack = CreateCmd(InnerDesigner.cmdSendToBack);
  262. cmdInsert = CreateCmd(InnerDesigner.cmdInsert);
  263. cmdInsertBand = CreateCmd(InnerDesigner.cmdInsertBand);
  264. cmdRecentFiles = new RecentFilesCommand(this, InnerDesigner.cmdRecentFiles);
  265. cmdSelectLanguage = CreateCmd(InnerDesigner.cmdSelectLanguage);
  266. cmdViewStartPage = CreateCmd(InnerDesigner.cmdViewStartPage);
  267. cmdReportSettings = CreateCmd(InnerDesigner.cmdReportSettings);
  268. cmdOptions = CreateCmd(InnerDesigner.cmdOptions);
  269. cmdReportStyles = CreateCmd(InnerDesigner.cmdReportStyles);
  270. cmdReportValidation = CreateCmd(InnerDesigner.cmdReportValidation);
  271. cmdHelpContents = CreateCmd(InnerDesigner.cmdHelpContents);
  272. cmdAccount = CreateCmd(InnerDesigner.cmdAccount);
  273. cmdAbout = CreateCmd(InnerDesigner.cmdAbout);
  274. cmdPolySelectMove = CreateCmd(InnerDesigner.CmdPolySelectMove);
  275. cmdPolySelectPointer = CreateCmd(InnerDesigner.CmdPolySelectPointer);
  276. cmdPolySelectAddPoint = CreateCmd(InnerDesigner.CmdPolySelectAddPoint);
  277. cmdPolySelectBezier = CreateCmd(InnerDesigner.CmdPolySelectBezier);
  278. cmdPolySelectRemovePoint = CreateCmd(InnerDesigner.CmdPolySelectRemovePoint);
  279. }
  280. }
  281. }