2009-05-20 8 views
3

Ich habe einen Bericht Formular Designer vor langer Zeit für ein Datenbankprojekt geschrieben. Es wurde eine Menge Winapi-Magie verwendet, weshalb ich gezwungen war, einige Teile "richtig zu schreiben"..NET benutzerdefinierte Formular-Designer: Wie IMenuCommandService implementieren?

Dank einiger Artikel aus dem MSDN Magazin (here und here) und CodeProject konnte ich Designeroberfläche, Toolbox und Undo/Redo Engine implementieren.

  1. Jede Ressource, die ich bisher entdeckt habe, ist etwas veraltet. Können Sie auf einen neuen/umfassenden Artikel zeigen?

  2. -Code aus article oben erwähnt scheint nicht funktioniert.

    MenuCommandService.ShowContextMenu heißt aber nichts erscheint, da es keine DesignerVerbs in globalVerbs Sammlung. Sollte ich "Standard" hinzufügen, entsprach Designer-Aktionen wie Ausschneiden/Einfügen, manuell? Wenn ja, wie kann ich das erreichen?

+1

Ich habe nie eine gute Dokumentation in diesem Bereich gesehen. Info zum Erstellen von Designern für Steuerelemente, ja, aber nicht für das ganze Formular. Ich schlage vor, Sie verbringen Zeit damit, die Quelle mit Reflector oder der geteilten Quelle zu betrachten. –

Antwort

3

Dank SharpDevelop Quellen konnte ich die Lösung

Diese minimale Implementierung, um herauszufinden, (einige standart Befehle, nicht mehr) arbeitete für mich

using System; 
using System.Collections.Generic; 
using System.ComponentModel.Design; 
using System.Diagnostics; 
using System.Windows.Forms; 
using System.Drawing; 

namespace DesignerHost 
{ 
    class MenuCommandServiceImpl : MenuCommandService 
    { 
     DesignerVerbCollection m_globalVerbs = new DesignerVerbCollection(); 

     public MenuCommandServiceImpl(IServiceProvider serviceProvider) 
      : base(serviceProvider) 
     { 
      m_globalVerbs.Add(StandartVerb("Cut", StandardCommands.Cut)); 
      m_globalVerbs.Add(StandartVerb("Copy", StandardCommands.Copy)); 
      m_globalVerbs.Add(StandartVerb("Paste", StandardCommands.Paste)); 
      m_globalVerbs.Add(StandartVerb("Delete", StandardCommands.Delete)); 
      m_globalVerbs.Add(StandartVerb("Select All", StandardCommands.SelectAll)); 

     } 

     private DesignerVerb StandartVerb(string text, CommandID commandID) 
     { 
      return new DesignerVerb(text, 
       delegate(object o, EventArgs e) 
       { 
        IMenuCommandService ms = 
         GetService(typeof(IMenuCommandService)) as IMenuCommandService; 
        Debug.Assert(ms != null); 
        ms.GlobalInvoke(commandID); 
       } 
      ); 
     } 

     class MenuItem : ToolStripMenuItem 
     { 
      DesignerVerb verb; 

      public MenuItem(DesignerVerb verb) 
       : base(verb.Text) 
      { 
       Enabled = verb.Enabled; 
       this.verb = verb; 
       Click += InvokeCommand; 
      } 

      void InvokeCommand(object sender, EventArgs e) 
      { 
       try 
       { 
        verb.Invoke(); 
       } 
       catch (Exception ex) 
       { 
        Trace.Write("MenuCommandServiceImpl: " + ex.ToString()); 
       } 
      } 
     } 

     private ToolStripItem[] BuildMenuItems() 
     { 
      List<ToolStripItem> items = new List<ToolStripItem>(); 

      foreach (DesignerVerb verb in m_globalVerbs) 
      { 
       items.Add(new MenuItem(verb)); 
      } 
      return items.ToArray(); 
     } 

     #region IMenuCommandService Members 

     /// This is called whenever the user right-clicks on a designer. 
     public override void ShowContextMenu(CommandID menuID, int x, int y) 
     { 
      // Display our ContextMenu! Note that the coordinate parameters to this method 
      // are in screen coordinates, so we've got to translate them into client coordinates. 

      ContextMenuStrip cm = new ContextMenuStrip(); 
      cm.Items.AddRange(BuildMenuItems()); 

      ISelectionService ss = GetService(typeof (ISelectionService)) as ISelectionService; 
      Debug.Assert(ss != null); 

      Control ps = ss.PrimarySelection as Control; 
      Debug.Assert(ps != null); 

      Point s = ps.PointToScreen(new Point(0, 0)); 
      cm.Show(ps, new Point(x - s.X, y - s.Y)); 
     } 

     #endregion 

    } 
} 

aktualisieren

similar solution gefunden

+1

Ich weiß, spät, aber in die "ähnliche Lösung" gibt es ein Problem. Wenn Sie dort auf ein Menü klicken, ruft es das Verb mit GlobalInvoke (designerVerb.CommandID) auf. Es gibt Verben, die die gleiche CommandID haben (dh Add und Remove Tab von einem TabStrip, so dass die ähnliche Lösung nicht in jeder Bedingung funktioniert. Hier, bei einem Menüklick, wird die auszuführende Aktion mit DesignerVerb.Invoke() aufgerufen . – bubi

1

lief ich in gleiches Problem vor einem Monat und bekam etwas wirklich interessante und hilfreiche von CodePlex here. Ich lese darüber auf Brad Abram's Blog Post. Dazu gehören viele Beispiele zur Framework-Erweiterbarkeit und die benutzerdefinierte Windows Form Designer-Benutzeroberfläche ist einer davon.

Link-Txt 1: http://mef.codeplex.com/

Link-Txt 2: http://blogs.msdn.com/brada/archive/2009/04/13/managed-extensibility-framework-preview-5-released.aspx

Dank.

+0

Es gibt keine Arbeitsentwurfsoberfläche Kontextmenü hier Anscheinend MEF Studio Designer auf dieser MSDN Code basiert http://msdn.microsoft.com/en-us/magazine/cc163634.aspx – jonny

Verwandte Themen