using FastReport.Design.StandardDesigner; using FastReport.Utils; using System; using System.ComponentModel; using System.Windows; using System.Windows.Controls; namespace FastReport.Design { /// /// Represents the standard report designer. /// public partial class WpfDesignerControl : UserControl { #region Properties /// /// Gets inner designer control. /// public DesignerControl InnerDesigner { get; } /// /// Gets or sets the edited report. /// /// /// To initialize the designer, you need to pass a Report instance to this property. /// This will create the designer's surface associated with the report. /// public Report Report { get => InnerDesigner.Report; set => InnerDesigner.Report = value; } /// /// Gets or sets the visual style. /// public UIStyle UIStyle { get => InnerDesigner.UIStyle; set => InnerDesigner.UIStyle = value; } /// /// Gets or sets a value indicating whether the main menu should be displayed or not. /// public bool ShowMainMenu { get => InnerDesigner.ShowMainMenu; set => InnerDesigner.ShowMainMenu = value; } /// /// Gets or sets a value indicating whether the status bar should be displayed or not. /// public bool ShowStatusBar { get => InnerDesigner.ShowStatusBar; set => InnerDesigner.ShowStatusBar = value; } /// /// Gets or sets the zoom factor. /// public float Zoom { get => InnerDesigner.Zoom; set => InnerDesigner.Zoom = value; } /// /// Gets or sets the layout state of the designer. /// /// /// You may use this property to save and restore the designer's layout in your code. However, consider using the /// and methods that use FastReport configuration file. /// public string LayoutState { get => InnerDesigner.LayoutState; set => InnerDesigner.LayoutState = value; } /// /// Gets or sets a value that determines whether the control should handle the window's Closing event. /// public bool HandleWindowEvents { get; set; } = true; /// /// Occurs when the designer's UI state is changed. /// /// /// Use this event to update state of your own controls bound to the designer's commands. /// public event EventHandler UIStateChanged { add => InnerDesigner.UIStateChanged += value; remove => InnerDesigner.UIStateChanged -= value; } #endregion #region Commands public DesignerCommand cmdNew { get; } public DesignerCommand cmdNewPage { get; } public DesignerCommand cmdNewDialog { get; } public OpenCommand cmdOpen { get; } public DesignerCommand cmdOpenPage { get; } public DesignerCommand cmdOpenViaCloud { get; } public DesignerCommand cmdSave { get; } public DesignerCommand cmdSaveToCloud { get; } public DesignerCommand cmdSaveAs { get; } public DesignerCommand cmdSaveWithRandomData { get; } public DesignerCommand cmdSaveAll { get; } public DesignerCommand cmdClose { get; } public DesignerCommand cmdCloseAll { get; } public DesignerCommand cmdPreview { get; } public DesignerCommand cmdPreviewCloud { get; } public DesignerCommand cmdPrinterSetup { get; } public DesignerCommand cmdPageSetup { get; } public DesignerCommand cmdAddData { get; } public DesignerCommand cmdSortDataSources { get; } public DesignerCommand cmdChooseData { get; } public DesignerCommand cmdUndo { get; } public DesignerCommand cmdRedo { get; } public DesignerCommand cmdCut { get; } public DesignerCommand cmdCopy { get; } public DesignerCommand cmdPaste { get; } public DesignerCommand cmdFormatPainter { get; } public DesignerCommand cmdDelete { get; } public DesignerCommand cmdCopyPage { get; } public DesignerCommand cmdDeletePage { get; } public DesignerCommand cmdSelectAll { get; } public DesignerCommand cmdGroup { get; } public DesignerCommand cmdUngroup { get; } public DesignerCommand cmdEdit { get; } public DesignerCommand cmdFind { get; } public DesignerCommand cmdReplace { get; } public DesignerCommand cmdBringToFront { get; } public DesignerCommand cmdSendToBack { get; } public DesignerCommand cmdInsert { get; } public DesignerCommand cmdInsertBand { get; } public RecentFilesCommand cmdRecentFiles { get; } public DesignerCommand cmdSelectLanguage { get; } public DesignerCommand cmdViewStartPage { get; } public DesignerCommand cmdReportSettings { get; } public DesignerCommand cmdOptions { get; } public DesignerCommand cmdReportStyles { get; } public DesignerCommand cmdReportValidation { get; } public DesignerCommand cmdHelpContents { get; } public DesignerCommand cmdAccount { get; } public DesignerCommand cmdAbout { get; } public DesignerCommand cmdPolySelectMove { get; } public DesignerCommand cmdPolySelectPointer { get; } public DesignerCommand cmdPolySelectAddPoint { get; } public DesignerCommand cmdPolySelectBezier { get; } public DesignerCommand cmdPolySelectRemovePoint { get; } #endregion #region Methods /// /// Saves config to a FastReport configuration file. /// public void SaveConfig() => InnerDesigner.SaveConfig(); /// /// Restores config from a FastReport configuration file. /// /// /// Call this method to restore the designer's layout. You need to do this after the /// designer's control is placed on a form. /// public void RestoreConfig() => InnerDesigner.RestoreConfig(); /// /// AutoSave system initialization. /// public void StartAutoSave() => InnerDesigner.StartAutoSave(); /// /// Stops the AutoSave system. /// public void StopAutoSave() => InnerDesigner.StopAutoSave(); /// /// Checks if parent window can be closed. /// /// The cancel event args. /// /// Use this method in the window's Closing event handler if you set to false. /// 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. /// public void ParentWindowClosing(CancelEventArgs e) { if (e.Cancel) return; var args = new System.Windows.Forms.FormClosingEventArgs(System.Windows.Forms.CloseReason.UserClosing, false); InnerDesigner.ParentFormClosing(args); e.Cancel = args.Cancel; } #endregion private DesignerCommand CreateCmd(FastReport.Design.DesignerCommand innerCommand) => new DesignerCommand(this, innerCommand); /// /// Initializes a new instance of the class. /// public WpfDesignerControl() { InnerDesigner = new DesignerControl(); var control = InnerDesigner.control; control.Width = double.NaN; control.Height = double.NaN; control.HorizontalAlignment = HorizontalAlignment.Stretch; control.VerticalAlignment = VerticalAlignment.Stretch; Content = control; UseLayoutRounding = true; Loaded += (s, e) => { var window = Window.GetWindow(this); if (window == null) return; System.Windows.Forms.DpiRescaler.Install(window, InnerDesigner, this, (s, e) => InnerDesigner.UpdateDpiDependencies(null)); // update toolbar area InnerDesigner.UpdateUIStyle(); // WPF bug: designer workspace is not initialized if the dialog form is the first page in a report (reason: visible designer form is needed) InnerDesigner.UpdateFirstDialogPage(); // handle parent window events if (HandleWindowEvents) { RestoreConfig(); StartAutoSave(); window.Closing += (s, e) => { ParentWindowClosing(e); if (!e.Cancel) { SaveConfig(); StopAutoSave(); } }; } }; cmdNew = CreateCmd(InnerDesigner.cmdNew); cmdNewPage = CreateCmd(InnerDesigner.cmdNewPage); cmdNewDialog = CreateCmd(InnerDesigner.cmdNewDialog); cmdOpen = new OpenCommand(this, InnerDesigner.cmdOpen); cmdOpenPage = CreateCmd(InnerDesigner.cmdOpenPage); cmdOpenViaCloud = CreateCmd(InnerDesigner.cmdOpenViaCloud); cmdSave = CreateCmd(InnerDesigner.cmdSave); cmdSaveToCloud = CreateCmd(InnerDesigner.cmdSaveToCloudCommand); cmdSaveAs = CreateCmd(InnerDesigner.cmdSaveAs); cmdSaveWithRandomData = CreateCmd(InnerDesigner.cmdSaveWithRandomData); cmdSaveAll = CreateCmd(InnerDesigner.cmdSaveAll); cmdClose = CreateCmd(InnerDesigner.cmdClose); cmdCloseAll = CreateCmd(InnerDesigner.cmdCloseAll); cmdPreview = CreateCmd(InnerDesigner.cmdPreview); cmdPreviewCloud = CreateCmd(InnerDesigner.cmdPreviewCloud); cmdPrinterSetup = CreateCmd(InnerDesigner.cmdPrinterSetup); cmdPageSetup = CreateCmd(InnerDesigner.cmdPageSetup); cmdAddData = CreateCmd(InnerDesigner.cmdAddData); cmdSortDataSources = CreateCmd(InnerDesigner.cmdSortDataSources); cmdChooseData = CreateCmd(InnerDesigner.cmdChooseData); cmdUndo = CreateCmd(InnerDesigner.cmdUndo); cmdRedo = CreateCmd(InnerDesigner.cmdRedo); cmdCut = CreateCmd(InnerDesigner.cmdCut); cmdCopy = CreateCmd(InnerDesigner.cmdCopy); cmdPaste = CreateCmd(InnerDesigner.cmdPaste); cmdFormatPainter = CreateCmd(InnerDesigner.cmdFormatPainter); cmdDelete = CreateCmd(InnerDesigner.cmdDelete); cmdCopyPage = CreateCmd(InnerDesigner.cmdCopyPage); cmdDeletePage = CreateCmd(InnerDesigner.cmdDeletePage); cmdSelectAll = CreateCmd(InnerDesigner.cmdSelectAll); cmdGroup = CreateCmd(InnerDesigner.cmdGroup); cmdUngroup = CreateCmd(InnerDesigner.cmdUngroup); cmdEdit = CreateCmd(InnerDesigner.cmdEdit); cmdFind = CreateCmd(InnerDesigner.cmdFind); cmdReplace = CreateCmd(InnerDesigner.cmdReplace); cmdBringToFront = CreateCmd(InnerDesigner.cmdBringToFront); cmdSendToBack = CreateCmd(InnerDesigner.cmdSendToBack); cmdInsert = CreateCmd(InnerDesigner.cmdInsert); cmdInsertBand = CreateCmd(InnerDesigner.cmdInsertBand); cmdRecentFiles = new RecentFilesCommand(this, InnerDesigner.cmdRecentFiles); cmdSelectLanguage = CreateCmd(InnerDesigner.cmdSelectLanguage); cmdViewStartPage = CreateCmd(InnerDesigner.cmdViewStartPage); cmdReportSettings = CreateCmd(InnerDesigner.cmdReportSettings); cmdOptions = CreateCmd(InnerDesigner.cmdOptions); cmdReportStyles = CreateCmd(InnerDesigner.cmdReportStyles); cmdReportValidation = CreateCmd(InnerDesigner.cmdReportValidation); cmdHelpContents = CreateCmd(InnerDesigner.cmdHelpContents); cmdAccount = CreateCmd(InnerDesigner.cmdAccount); cmdAbout = CreateCmd(InnerDesigner.cmdAbout); cmdPolySelectMove = CreateCmd(InnerDesigner.CmdPolySelectMove); cmdPolySelectPointer = CreateCmd(InnerDesigner.CmdPolySelectPointer); cmdPolySelectAddPoint = CreateCmd(InnerDesigner.CmdPolySelectAddPoint); cmdPolySelectBezier = CreateCmd(InnerDesigner.CmdPolySelectBezier); cmdPolySelectRemovePoint = CreateCmd(InnerDesigner.CmdPolySelectRemovePoint); } } }