diff --git a/CADability/MenuResource.cs b/CADability/MenuResource.cs
index 3a111d44..85abf613 100644
--- a/CADability/MenuResource.cs
+++ b/CADability/MenuResource.cs
@@ -304,14 +304,16 @@ static public MenuWithHandler[] CreateContextMenuWithHandler(string[] menuIDs, I
/// Name of the menu to load: the "Name" attribute of a "MainMenu" node or the "MenuId" attribute of a "Popup" node
/// true to load a main menu, false to load a popup (context) menu
/// Command handler which handles the menu commands
- /// The menu entries
+ /// The menu entries, an empty array if there is no menu with this name (e.g. for a null name)
static public MenuWithHandler[] LoadMenuDefinition(string MenuName, bool main, ICommandHandler handler)
{
List result = new List();
ICommandHandler Handler = handler;
+ if (MenuName == null) return result.ToArray(); // e.g. an object without a context menu of its own, like a picture
XmlNode MenuNode;
if (main) MenuNode = mMenuDocument.SelectSingleNode("Menus/MainMenu[@Name='" + MenuName + "']");
else MenuNode = mMenuDocument.SelectSingleNode("Menus//Popup[@MenuId='" + MenuName + "']");
+ if (MenuNode == null) return result.ToArray();
for (XmlNode nd = MenuNode.FirstChild; nd != null; nd = nd.NextSibling)
{
LoadMenu(nd, result, Handler);
diff --git a/CADability/UnscaledGeoObject.cs b/CADability/UnscaledGeoObject.cs
index 6e454eed..4d211e9c 100644
--- a/CADability/UnscaledGeoObject.cs
+++ b/CADability/UnscaledGeoObject.cs
@@ -343,7 +343,7 @@ IGeoObject IGeoObjectShowProperty.GetGeoObject()
string IGeoObjectShowProperty.GetContextMenuId()
{
- throw new Exception("The method or operation is not implemented.");
+ return null; // no context menu of its own
}
#endregion
diff --git a/CADability/UnscaledIcon.cs b/CADability/UnscaledIcon.cs
index fd6a82f6..639bc6c7 100644
--- a/CADability/UnscaledIcon.cs
+++ b/CADability/UnscaledIcon.cs
@@ -338,7 +338,7 @@ IGeoObject IGeoObjectShowProperty.GetGeoObject()
string IGeoObjectShowProperty.GetContextMenuId()
{
- throw new Exception("The method or operation is not implemented.");
+ return null; // no context menu of its own
}
#endregion
diff --git a/tests/CADability.Tests/ContextMenuTests.cs b/tests/CADability.Tests/ContextMenuTests.cs
new file mode 100644
index 00000000..f78d77a4
--- /dev/null
+++ b/tests/CADability.Tests/ContextMenuTests.cs
@@ -0,0 +1,45 @@
+using CADability.GeoObject;
+using CADability.UserInterface;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace CADability.Tests
+{
+ ///
+ /// The context menu of a selected object: loads the menu whose id the object's
+ /// returns. Pictures, icons and unscaled objects have no menu of their own and
+ /// return null; a right click on a selected picture threw a NullReferenceException in
+ /// .
+ ///
+ [TestClass]
+ public class ContextMenuTests
+ {
+ [TestMethod]
+ public void AMissingMenuIsEmpty()
+ {
+ Assert.AreEqual(0, MenuResource.LoadMenuDefinition(null, false, null).Length);
+ Assert.AreEqual(0, MenuResource.LoadMenuDefinition("MenuId.DoesNotExist", false, null).Length);
+ Assert.AreEqual(0, MenuResource.LoadMenuDefinition("No Such Main Menu", true, null).Length);
+ }
+
+ [TestMethod]
+ public void AnExistingMenuIsLoaded()
+ {
+ // the context menu of the path of a picture
+ MenuWithHandler[] menu = MenuResource.LoadMenuDefinition("MenuId.Picture.Path", false, null);
+ CollectionAssert.AreEqual(new[] { "MenuId.Picture.Path.Reload", "MenuId.Picture.Path.Open" }, menu.Select(m => m.ID).ToArray());
+ }
+
+ [TestMethod]
+ [DataRow(typeof(ShowPropertyPicture))]
+ [DataRow(typeof(ShowPropertyUnscaledIcon))]
+ [DataRow(typeof(ShowPropertyUnscaledGeoObject))]
+ public void TheContextMenuOfObjectsWithoutAMenuOfTheirOwnCanBeLoaded(Type showPropertyType)
+ {
+ // what SelectObjectsAction.OnMouseUp does for a single selected object; the id does not depend on the state
+ // of the property, so an uninitialized one (without a frame) is enough
+ IGeoObjectShowProperty showProperty = (IGeoObjectShowProperty)System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject(showPropertyType);
+ MenuWithHandler[] menu = MenuResource.LoadMenuDefinition(showProperty.GetContextMenuId(), false, showProperty as ICommandHandler);
+ Assert.AreEqual(0, menu.Length);
+ }
+ }
+}