.NET designer formulaire personnalisé: Comment mettre en œuvre IMenuCommandService?
-
23-08-2019 - |
Question
J'ai un concepteur de formulaire de rapport écrit il y a longtemps pour un projet de base de données. Il a utilisé beaucoup de magie winapi donc j'ai été obligé de réécrire certaines parties « de la manière appropriée ».
Merci à certains articles du magazine MSDN ( et < a href = "http://msdn.microsoft.com/en-us/magazine/cc163634.aspx" rel = "nofollow noreferrer"> ici ) et CodeProject je suis en mesure de mettre en œuvre la surface de concepteur, boîte à outils et défaire / moteur redo.
-
Toutes les ressources que j'ai découvert sur le sujet à ce jour est un peu vieillot. Pouvez-vous indiquer à l'article frais / complet?
-
article mentionné ci-dessus semble ne fonctionne pas .
MenuCommandService.ShowContextMenu est appelé, mais rien ne semble car il n'y a pas de DesignerVerbs dans la collecte de globalVerbs. Dois-je ajouter les « standard », ont correspondu à des actions de créateurs tels que couper / coller, manuellement? Si oui, comment puis-je y arriver?
La solution
Merci aux sources SharpDevelop j'ai pu trouver la solution
Cette mise en œuvre minimale (quelques commandes standart, pas plus) a fonctionné pour moi
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
}
}
Mise à jour
Autres conseils
Je suis tombé sur un même problème il y a mois et a obtenu quelque chose de vraiment interessant et utile de CodePlex . Je lis à ce sujet sur Blog de Brad Abram post. Ceux-ci comprend de nombreux exemples sur l'extensibilité-cadre et formulaire personnalisé de Windows Interface Designer est l'un d'entre eux.
Txt 1: http://mef.codeplex.com/
Merci.