using System; using System.ComponentModel.Design; using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.Design; namespace AeroWizard.Design { internal class WizardPageDesigner : RichParentControlDesigner { private static readonly string[] propsToRemove = new string[] { "Anchor", "AutoScrollOffset", "AutoSize", "BackColor", "BackgroundImage", "BackgroundImageLayout", "ContextMenuStrip", "Cursor", "Dock", "Enabled", "Font", "ForeColor", "Location", "Margin", "MaximumSize", "MinimumSize", "Padding", "TabStop", "UseWaitCursor", "Visible" }; public override SelectionRules SelectionRules => SelectionRules.Visible | SelectionRules.Locked; protected override bool EnableDragRect => false; public override bool CanBeParentedTo(IDesigner parentDesigner) => parentDesigner?.Component is WizardPageContainer; internal WizardBaseDesigner ContainerDesigner => GetService()?.GetDesigner(Control.Owner) as WizardBaseDesigner; public override void Initialize(System.ComponentModel.IComponent component) { base.Initialize(component); //base.Glyphs.Add(new WizardPageDesignerGlyph(this)); GetService()?.Remove(component); } internal void OnDragDropInternal(DragEventArgs de) { OnDragDrop(de); } internal void OnDragEnterInternal(DragEventArgs de) { OnDragEnter(de); } internal void OnDragLeaveInternal(EventArgs e) { OnDragLeave(e); } internal void OnDragOverInternal(DragEventArgs e) { OnDragOver(e); } internal void OnGiveFeedbackInternal(GiveFeedbackEventArgs e) { OnGiveFeedback(e); } protected override void OnPaintAdornments(PaintEventArgs pe) { var clientRectangle = Control.ClientRectangle; clientRectangle.Width--; clientRectangle.Height--; ControlPaint.DrawFocusRectangle(pe.Graphics, clientRectangle); base.OnPaintAdornments(pe); } protected override System.Collections.Generic.IEnumerable PropertiesToRemove => propsToRemove; internal class WizardPageDesignerActionList : RichDesignerActionList { public WizardPageDesignerActionList(WizardPageDesigner pageDesigner, WizardPage page) : base(pageDesigner, page) { } [DesignerActionProperty("Back Button Enabled", 0, Category = "Buttons", Description = "Enables the Back button when this page is shown.")] public bool AllowBack { get { return Component.AllowBack; } set { Component.AllowBack = value; } } [DesignerActionProperty("Cancel Button Enabled", 1, Category = "Buttons", Description = "Enables the Cancel button when this page is shown.")] public bool AllowCancel { get { return Component.AllowCancel; } set { Component.AllowCancel = value; } } [DesignerActionProperty("Next Button Enabled", 3, Category = "Buttons")] public bool AllowNext { get { return Component.AllowNext; } set { Component.AllowNext = value; } } [DesignerActionProperty("Mark As Finish Page", 5, Category = "Behavior")] public bool IsFinishPage { get { return Component.IsFinishPage; } set { Component.IsFinishPage = value; } } [DesignerActionProperty("Set Next Page", 6, Category = "Behavior")] public WizardPage NextPage { get { return Component.NextPage; } set { Component.NextPage = value; } } [DesignerActionProperty("Cancel Button Visible", 2, Category = "Buttons")] public bool ShowCancel { get { return Component.ShowCancel; } set { Component.ShowCancel = value; } } [DesignerActionProperty("Next Button Visible", 4, Category = "Behavior")] public bool ShowNext { get { return Component.ShowNext; } set { Component.ShowNext = value; } } } } internal class WizardPageDesignerBehavior : RichBehavior { public WizardPageDesignerBehavior(WizardPageDesigner designer) : base(designer) { } public override bool OnMouseDown(System.Windows.Forms.Design.Behavior.Glyph g, MouseButtons button, Point mouseLoc) { if (button == MouseButtons.Left) { switch (((WizardPageDesignerGlyph)g).LastHit) { case WizardPageDesignerGlyph.ClickState.FirstBtn: Designer.Control.Owner.SelectedPage = Designer.Control.Owner.Pages[0]; break; case WizardPageDesignerGlyph.ClickState.PrevBtn: Designer.Control.Owner.PreviousPage(); break; case WizardPageDesignerGlyph.ClickState.NextBtn: Designer.Control.Owner.NextPage(); break; case WizardPageDesignerGlyph.ClickState.LastBtn: Designer.Control.Owner.SelectedPage = Designer.Control.Owner.Pages[Designer.Control.Owner.Pages.Count - 1]; break; case WizardPageDesignerGlyph.ClickState.Control: break; default: throw new ArgumentOutOfRangeException(); } } return base.OnMouseDown(g, button, mouseLoc); } } internal class WizardPageDesignerGlyph : RichGlyph { private const int btnCount = 4, btnSize = 16, navBoxWidth = btnSize*btnCount + (btnCount - 1)*2 + 4, navBoxHeight = btnSize + 4; private Rectangle navBox; public WizardPageDesignerGlyph(WizardPageDesigner designer) : base(designer, new WizardPageDesignerBehavior(designer)) { Designer.SelectionService.SelectionChanged += selSvc_SelectionChanged; Designer.Control.Move += control_Move; Designer.Control.Resize += control_Move; } internal enum ClickState { Control, FirstBtn, PrevBtn, NextBtn, LastBtn } public override Rectangle Bounds => navBox; internal ClickState LastHit { get; set; } public override void Dispose() { Designer.SelectionService.SelectionChanged -= selSvc_SelectionChanged; Designer.Control.Move -= control_Move; Designer.Control.Resize -= control_Move; base.Dispose(); } public override Cursor GetHitTest(Point p) { var r1 = new Rectangle(navBox.X + 2, navBox.Y + 2, btnSize, btnSize); for (var i = 0; i < btnCount; i++) { if (r1.Contains(p)) { LastHit = (ClickState)(i + 1); return Cursors.Arrow; } r1.Offset(btnSize + 2, 0); } LastHit = ClickState.Control; return null; } public override void Paint(PaintEventArgs pe) { var isMin7 = Environment.OSVersion.Version >= new Version(6, 1); var fn = isMin7 ? "Webdings" : "Arial Narrow"; var btnText = isMin7 ? new[] {"9", "3", "4", ":"} : new[] {"«", "<", ">", "»"}; using (var f = new Font(fn, btnSize - 2, isMin7 ? FontStyle.Regular : FontStyle.Bold, GraphicsUnit.Pixel)) { pe.Graphics.FillRectangle(SystemBrushes.Control, new Rectangle(navBox.X, navBox.Y, navBox.Width + 1, navBox.Height + 1)); using (var pen = new Pen(SystemBrushes.ControlDark, 1f) {DashStyle = System.Drawing.Drawing2D.DashStyle.Dot}) { pe.Graphics.DrawRectangle(pen, navBox); var r1 = new Rectangle(navBox.X + 2, navBox.Y + 2, btnSize, btnSize); pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; var sf = new StringFormat() {Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center}; for (var i = 0; i < btnCount; i++) { pe.Graphics.DrawRectangle(pen, r1); r1.Offset(1, 1); //TextRenderer.DrawText(pe.Graphics, btnText[i], f, r1, SystemColors.ControlDark, SystemColors.Window, TextFormatFlags.NoPadding | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter); pe.Graphics.DrawString(btnText[i], f, SystemBrushes.ControlDark, r1, sf); r1.Offset(btnSize + 1, -1); } } } } private void control_Move(object sender, EventArgs e) { if (ReferenceEquals(Designer.SelectionService.PrimarySelection, Designer.Control)) { SetNavBoxes(); Designer.Adorner.Invalidate(); } } private void selSvc_SelectionChanged(object sender, EventArgs e) { if (ReferenceEquals(Designer.SelectionService.PrimarySelection, Designer.Control)) { SetNavBoxes(); Designer.Adorner.Enabled = true; Designer.Control.Owner.DesignerSelected = true; } else if (Designer.Control.Owner.DesignerSelected) { Designer.Adorner.Enabled = false; Designer.Control.Owner.DesignerSelected = false; } } private void SetNavBoxes() { var pt = Designer.BehaviorService.ControlToAdornerWindow(Designer.Control); navBox = new Rectangle(pt.X + Designer.Control.Width - navBoxWidth - 17, pt.Y - navBoxHeight - 5, navBoxWidth, navBoxHeight); } } }