This series of CodeProject articles is based on a series of posts I've first published on my blog.
Windows Ribbon for WinForms library now supports using a Context Popup. The result of this post is yet another sample, "15-ContextPopup", found on the project site.
What is a Context Popup?
A context popup is a combination of a small toolbar (called MiniToolbar) and a context menu, which a ribbon enabled application can provide. This popup usually appears when right-clicking an application surface, and it usually provides common operations relevant for the clicked surface. Basically, it's just another way to get to your ribbon commands. In fact, since the MiniToolbar (the upper part of the context popup) can't be accessed using the keyboard, Microsoft strongly recommends that every command should also be available using the standard ribbon interface.
More details can be found at Context Popup on MSDN.
Using ContextPopup - Ribbon Markup
Following is an example of defining a context popup. Only the Views section is presented since the Commands section is obvious. The result of this markup is shown in the image above.
<Application.Views>
<ContextPopup>
<ContextPopup.MiniToolbars>
<MiniToolbar Name="MiniToolbar">
<MenuGroup>
<FontControl CommandName="cmdFontControl"/>
</MenuGroup>
<MenuGroup>
<DropDownColorPicker CommandName="cmdDropDownColorPicker" />
<Button CommandName="cmdButtonNew" />
<Button CommandName="cmdButtonOpen" />
<Button CommandName="cmdButtonSave" />
<ComboBox />
</MenuGroup>
</MiniToolbar>
</ContextPopup.MiniToolbars>
<ContextPopup.ContextMenus>
<ContextMenu Name="ContextMenu">
<MenuGroup>
<Button CommandName="cmdButtonNew" />
<Button CommandName="cmdButtonOpen" />
<Button CommandName="cmdButtonSave" />
</MenuGroup>
<MenuGroup>
<DropDownColorPicker CommandName="cmdDropDownColorPicker" />
</MenuGroup>
</ContextMenu>
</ContextPopup.ContextMenus>
<ContextPopup.ContextMaps>
<ContextMap CommandName="cmdContextMap"
ContextMenu="ContextMenu"
MiniToolbar="MiniToolbar" />
</ContextPopup.ContextMaps>
</ContextPopup>
<Ribbon>
</Ribbon>
</Application.Views>
Things to note:
- In the
ContextPopup.MiniToolbars
element, you can define a list of available mini toolbars (upper parts). - In the
ContextPopup.ContextMenus
element, you can define a list of available context menus (lower parts). - The actual definition of the context popup resides in the
ContextPopup.ContextMaps
element, where you can define a list of context popups. For each context popup, you need to specify its upper part and lower part.
Using ContextPopup - Code-Behind
In order to show the predefined context popups, I present here two ways: the recommended way and the convenient way.
The recommended way: use the method Ribbon.ShowContextPopup
to show a given context popup in a certain location, usually as a response to right clicking:
private Ribbon _ribbon;
public Form1()
{
InitializeComponent();
_ribbon = new Ribbon();
panel2.MouseClick += new MouseEventHandler(panel2_MouseClick);
}
void panel2_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
System.Drawing.Point p = panel2.PointToScreen(e.Location);
_ribbon.ShowContextPopup((uint)RibbonMarkupCommands.cmdContextMap, p.X, p.Y);
}
}
Note that ShowContextPopup
gets the location in screen coordinates, so a transformation using the Control.PointToScreen
method is required.
The convenient way: if you are used to program client applications in .NET, you must be familiar with ContextMenuStrip
class. Every WinForms control has a ContextMenuStrip
property where you can attach an instance of a predefined ContextMenuStrip
instance, thus letting the .NET framework handle the opening of the context menu for you. Unfortunately, the ContextMenuStrip
property works only with ContextMenuStrip
instances (an IContextMenuStrip
interface would be great..), so you can't easily replace the .NET implementation of a context menu with our new ribbon based implementation.
Following is a hack you can use to achieve this. I've created a RibbonContextMenuStrip
class that inherits from ContextMenuStrip
and hacked my way into showing the ribbon context menu instead of the .NET context menu. The advantage is that you have an easier interface for working with the ribbon context menu:
private Ribbon _ribbon;
private RibbonContextMenuStrip _ribbonContextMenuStrip;
public Form1()
{
InitializeComponent();
_ribbon = new Ribbon();
_ribbonContextMenuStrip = new RibbonContextMenuStrip(_ribbon,
(uint)RibbonMarkupCommands.cmdContextMap);
panel1.ContextMenuStrip = _ribbonContextMenuStrip;
}
As you can see from the code, it is shorter and uses the standard .NET way for setting context menus on controls.
Let's see the "magic" in action:
public class RibbonContextMenuStrip : ContextMenuStrip
{
private uint _contextPopupID;
private Ribbon _ribbon;
public RibbonContextMenuStrip(Ribbon ribbon, uint contextPopupID)
: base()
{
_contextPopupID = contextPopupID;
_ribbon = ribbon;
}
protected override void OnOpening(CancelEventArgs e)
{
_ribbon.ShowContextPopup(_contextPopupID,
Cursor.Position.X,
Cursor.Position.Y);
e.Cancel = true;
}
}
Note: The RibbonContextMenuStrip
is not part of the Windows Ribbon for WinForms library. The code is available as part of the sample "15-ContextPopup". It works, but I don't like it.
Ribbon Properties
This section has nothing to do with the context popup.
The ribbon library now supports three general properties for the ribbon UI:
Minimized
- Specifies whether the ribbon is in a collapsed or expanded state. Property Identifier: UI_PKey_Minimized
.Viewable
- Specifies whether the ribbon user interface (UI) is in a visible or hidden state. Property Identifier: UI_PKey_Viewable
.QuickAccessToolbarDock
- Specifies whether the quick access toolbar is docked at the top or at the bottom. Property Identifier: UI_PKey_QuickAccessToolbarDock
.
Using these properties is as simple as:
private void Form1_Load(object sender, EventArgs e)
{
_ribbon.InitFramework(this);
_ribbon.Viewable = false;
}
That's it for now.