//public static string GetNodeName(CodeGenerateSystem.Base.UsefulMemberHostData usefulMemberData) //{ // if (usefulMemberData != null && usefulMemberData.HostControl != null) // { // var name = usefulMemberData.HostControl.NodeName; // var index = name.IndexOf("("); // if (index > 0) // { // name = name.Substring(0, index); // } // return name.Replace(".", "-"); // } // return string.Empty; //} // 添加属性节点 public static CodeGenerateSystem.Controls.NodeListAttributeClass AddPropertyNode(CodeGenerateSystem.Controls.NodesContainerControl.ContextMenuFilterData filterData, PropertyInfo propertyInfo, Type parentClassType, CodeGenerateSystem.Controls.NodeListControl hostNodesList, CodeDomNode.PropertyInfoAssist.enDirection direction, EngineNS.ECSType csType, string attributeName, CodeDomNode.MethodInfoAssist.enHostType hostType) { // "CSUtility.Event.Attribute.AllowMember" // "CSUtility.AISystem.Attribute.AllowMember" var att = EngineNS.Rtti.AttributeHelper.GetCustomAttribute(propertyInfo, attributeName, true); if (att == null) { return(null); } var description = EngineNS.Rtti.AttributeHelper.GetCustomAttributePropertyValue(att, "Description").ToString(); string path = EngineNS.Rtti.AttributeHelper.GetCustomAttributePropertyValue(att, "Path")?.ToString(); if (string.IsNullOrEmpty(path)) { path = EngineNS.Rtti.RttiHelper.GetAppTypeString(propertyInfo.ReflectedType) + "." + propertyInfo.Name; } var csParam = new CodeDomNode.PropertyNode.PropertyNodeConstructionParams() { CSType = csType, ConstructParam = "", PropertyInfo = CodeDomNode.PropertyNode.GetAssistFromPropertyInfo(propertyInfo, parentClassType, direction, path, hostType), }; var mpattr = propertyInfo.GetCustomAttributes(typeof(EngineNS.Editor.MacrossPanelPathAttribute), false); if (mpattr.Length > 0) { path = ((EngineNS.Editor.MacrossPanelPathAttribute)mpattr[0]).Path; } else { path = path.Replace('.', '/'); } var displayattr = propertyInfo.GetCustomAttributes(typeof(System.ComponentModel.DisplayNameAttribute), false); if (displayattr.Length > 0) { csParam.DisplayName = ((System.ComponentModel.DisplayNameAttribute)displayattr[0]).DisplayName; } var attribute = hostNodesList.AddNodesFromType(filterData, typeof(CodeDomNode.PropertyNode), $"{path}({PropertyNode.GetParamPreInfo(direction)})", csParam, description); return(attribute); }
private void CreateParticleMethodCategory(string methodname, float x, float y) { Macross.NodesControlAssist NodesControlAssist = mLinkedNodesContainer.HostControl as Macross.NodesControlAssist; Type type = typeof(EngineNS.Bricks.Particle.AcceleratedNode); System.Reflection.MethodInfo methodInfo = type.GetMethod(methodname); var methodinfo = CodeDomNode.Program.GetMethodInfoAssistFromMethodInfo(methodInfo, type, CodeDomNode.MethodInfoAssist.enHostType.Base, ""); //加入列表信息 Macross.Category category; var csparam = CSParam as StructNodeControlConstructionParams; if (methodInfo.ReturnType.Equals(typeof(void))) { if (!csparam.CategoryDic.TryGetValue(Macross.MacrossPanelBase.GraphCategoryName, out category)) { return; } } else { if (!csparam.CategoryDic.TryGetValue(Macross.MacrossPanelBase.FunctionCategoryName, out category)) { return; } } var HostControl = this.HostNodesContainer.HostControl; var item = new Macross.CategoryItem(null, category); item.CategoryItemType = Macross.CategoryItem.enCategoryItemType.OverrideFunction; var data = new Macross.CategoryItem.InitializeData(); data.Reset(); var MacrossOpPanel = NodesControlAssist.HostControl.MacrossOpPanel; item.Initialize(MacrossOpPanel.HostControl, data); //HostControl.CreateNodesContainer(item); //MainGridItem.Children.Add(item); item.Name = methodname; category.Items.Add(item); //if (methodInfo.ReturnType.Equals(typeof(void)) == false) { var pnodeType = typeof(CodeDomNode.PropertyNode); var pncp = new CodeDomNode.PropertyNode.PropertyNodeConstructionParams(); pncp.CSType = mLinkedNodesContainer.CSType; pncp.HostNodesContainer = mLinkedNodesContainer; pncp.ConstructParam = ""; pncp.PropertyInfo = new CodeDomNode.PropertyInfoAssist() { PropertyName = "Accelerated", PropertyType = typeof(EngineNS.Vector3), HostType = CodeDomNode.MethodInfoAssist.enHostType.This, MacrossClassType = csparam.BaseClassName, Direction = CodeDomNode.PropertyInfoAssist.enDirection.Set, }; var pnode = mLinkedNodesContainer.AddNodeControl(pnodeType, pncp, x, y); } //加入结点信息 System.Reflection.ParameterInfo[] paramstype = methodInfo.GetParameters(); //拷貝方法的attribute. var attrts = methodInfo.GetCustomAttributes(true); string displayname = ""; for (int i = 0; i < attrts.Length; i++) { var displayattr = attrts[i] as System.ComponentModel.DisplayNameAttribute; if (displayattr != null) { displayname = displayattr.DisplayName; break; } } //var CustomFunctionData = new Macross.ResourceInfos.MacrossResourceInfo.CustomFunctionData(); var nodeType = typeof(CodeDomNode.MethodOverride); var csParam = new CodeDomNode.MethodOverride.MethodOverrideConstructParam() { CSType = mLinkedNodesContainer.CSType, HostNodesContainer = mLinkedNodesContainer, ConstructParam = "", MethodInfo = methodinfo, DisplayName = displayname, }; //var center = nodesContainer.NodesControl.GetViewCenter(); var node = mLinkedNodesContainer.AddOrigionNode(nodeType, csParam, x, y); node.IsDeleteable = false; //重写双击事件 不需要进入二级编辑 //item.OnDoubleClick -= item.OnDoubleClick; Type ItemType = item.GetType(); FieldInfo _Field = item.GetType().GetField("OnDoubleClick", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static); if (_Field != null) { object _FieldValue = _Field.GetValue(item); if (_FieldValue != null && _FieldValue is Delegate) { Delegate _ObjectDelegate = (Delegate)_FieldValue; Delegate[] invokeList = _ObjectDelegate.GetInvocationList(); foreach (Delegate del in invokeList) { ItemType.GetEvent("OnDoubleClick").RemoveEventHandler(item, del); } } } item.OnDoubleClick += (categoryItem) => { mLinkedNodesContainer.FocusNode(node); }; //NodesControlAssist.Save(); }
public UIMacrossEditorControl() { InitializeComponent(); Macross_Client.HostControl = this; Macross.CategoryItem.RegistInitAction("UI_UIElement_Variable", new Action <Macross.CategoryItem, Macross.IMacrossOperationContainer, Macross.CategoryItem.InitializeData>((item, ctrl, data) => { if (item.PropertyShowItem == null) { item.PropertyShowItem = new UIElementVariableCategoryItemPropertys(); } var varItemPro = item.PropertyShowItem as UIElementVariableCategoryItemPropertys; BindingOperations.SetBinding(varItemPro, UIElementVariableCategoryItemPropertys.VariableNameProperty, new Binding("Name") { Source = item }); BindingOperations.SetBinding(varItemPro, UIElementVariableCategoryItemPropertys.TooltipProperty, new Binding("ToolTips") { Source = item, Mode = BindingMode.TwoWay }); var initData = data as UIEditor.UIMacross.UIElementVariableCategoryItemInitData; BindingOperations.SetBinding(item, Macross.CategoryItem.NameProperty, new Binding("Name") { Source = initData.UIElement.Initializer }); varItemPro.VariableType = initData.ElementType; varItemPro.ElementId = initData.UIElementId; var atts = initData.ElementType.GetCustomAttributes(typeof(EngineNS.UISystem.Editor_UIControlAttribute), false); if (atts.Length > 0) { var att = atts[0] as EngineNS.UISystem.Editor_UIControlAttribute; item.Icon = new BitmapImage(new Uri($"/UIEditor;component/Icons/{att.Icon}", UriKind.Relative)); } var menuItem = new MenuItem() { Name = "VariableFocus", Header = "查找引用", Style = TryFindResource(new ComponentResourceKey(typeof(ResourceLibrary.CustomResources), "MenuItem_Default")) as Style, }; menuItem.Click += (object sender, RoutedEventArgs e) => { }; item.CategoryItemContextMenu.Items.Add(menuItem); item.OnDropToNodesControlAction = (dropData) => { var nodesControlAssist = dropData.NodesContainerHost as Macross.NodesControlAssist; nodesControlAssist.ShowGetButton = true; nodesControlAssist.ShowSetButton = false; nodesControlAssist.InitVariableDropShow(dropData.DropPos); }; item.OnDropVariableGetNodeControlAction = (actionData) => { var nodeType = typeof(CodeDomNode.PropertyNode); var csParam = new CodeDomNode.PropertyNode.PropertyNodeConstructionParams(); csParam.CSType = ctrl.CSType; csParam.HostNodesContainer = actionData.NodesContainer; csParam.ConstructParam = ""; csParam.PropertyInfo = new CodeDomNode.PropertyInfoAssist() { PropertyName = item.Name, PropertyType = varItemPro.VariableType, HostType = CodeDomNode.MethodInfoAssist.enHostType.This, MacrossClassType = HostControl.CurrentResInfo.ResourceName.PureName(), Direction = CodeDomNode.PropertyInfoAssist.enDirection.Get, }; var pos = actionData.NodesContainer._RectCanvas.TranslatePoint(actionData.Pos, actionData.NodesContainer._MainDrawCanvas); var node = actionData.NodesContainer.AddNodeControl(nodeType, csParam, pos.X, pos.Y); item.AddInstanceNode(actionData.NodesContainer.GUID, node); //nc.VariablePopupGetProcess(pos); }; })); Macross.CategoryItem.RegistInitAction("UI_UIElement_Event", new Action <Macross.CategoryItem, Macross.IMacrossOperationContainer, Macross.CategoryItem.InitializeData>((item, ctrl, data) => { var initData = data as UIElementEventCategoryItemInitData; item.Icon = TryFindResource("Icon_Function") as ImageSource; item.Name = initData.FunctionName + "___" + item.Id.ToString().Replace("-", "_"); item.ShowName = $"{initData.FunctionName}({initData.UIElement.Initializer.Name})"; Macross.CategoryItem.Delegate_OnDoubleClick action = async(categoryItem) => { var noUse = await ctrl.ShowNodesContainer(categoryItem); }; item.OnDoubleClick += action; if (item.PropertyShowItem == null) { item.PropertyShowItem = new UIElementEventCategoryItemPorpertys(); } var varItemPro = item.PropertyShowItem as UIElementEventCategoryItemPorpertys; varItemPro.MethodInfo.MethodName = item.Name; // initData.FunctionName + "_" + item.Id.ToString().Replace("-", "_"); varItemPro.MethodInfo.DisplayName = item.ShowName; // $"{initData.FunctionName}({initData.UIElement.Initializer.Name})"; var invokeMethod = initData.EventType.GetMethod("Invoke"); var methodParams = invokeMethod.GetParameters(); foreach (var methodParam in methodParams) { var funcParam = new CodeDomNode.CustomMethodInfo.FunctionParam(); funcParam.HostMethodInfo = varItemPro.MethodInfo; funcParam.ParamName = methodParam.Name; funcParam.ParamType = new CodeDomNode.VariableType(methodParam.ParameterType, ctrl.CSType); if (methodParam.IsOut) { varItemPro.MethodInfo.OutParams.Add(funcParam); } else { varItemPro.MethodInfo.InParams.Add(funcParam); } } if (invokeMethod.ReturnType != typeof(void) && invokeMethod.ReturnType != typeof(System.Threading.Tasks.Task)) { var funcParam = new CodeDomNode.CustomMethodInfo.FunctionParam(); funcParam.HostMethodInfo = varItemPro.MethodInfo; funcParam.ParamName = "Return"; if (invokeMethod.ReturnType.BaseType == typeof(System.Threading.Tasks.Task)) { var genericType = invokeMethod.ReturnType.GetGenericArguments()[0]; funcParam.ParamType = new CodeDomNode.VariableType(genericType, ctrl.CSType); varItemPro.MethodInfo.IsAsync = true; } else { funcParam.ParamType = new CodeDomNode.VariableType(invokeMethod.ReturnType, ctrl.CSType); } varItemPro.MethodInfo.OutParams.Add(funcParam); } else if (invokeMethod.ReturnType == typeof(System.Threading.Tasks.Task)) { varItemPro.MethodInfo.IsAsync = true; } initData.UIElement.Initializer.PropertyChanged += (sender, e) => { switch (e.PropertyName) { case "Name": item.ShowName = $"{initData.FunctionName}({initData.UIElement.Initializer.Name})"; varItemPro.MethodInfo.DisplayName = item.ShowName; break; } }; BindingOperations.SetBinding(varItemPro.MethodInfo, CodeDomNode.CustomMethodInfo.TooltipProperty, new Binding("ToolTips") { Source = item, Mode = BindingMode.TwoWay }); var menuItem = new MenuItem() { Name = "UIElementEventOpenGraph", Header = "打开", Style = TryFindResource(new ComponentResourceKey(typeof(ResourceLibrary.CustomResources), "MenuItem_Default")) as Style, }; menuItem.Click += (object sender, RoutedEventArgs e) => { action.Invoke(item); }; if (data.Deleteable) { menuItem = new MenuItem() { Name = "UIElementEventDelete", Header = "删除", Style = TryFindResource(new ComponentResourceKey(typeof(ResourceLibrary.CustomResources), "MenuItem_Default")) as Style, }; ResourceLibrary.Controls.Menu.MenuAssist.SetIcon(menuItem, new BitmapImage(new Uri("/ResourceLibrary;component/Icons/Icons/icon_Edit_Delete_40x.png", UriKind.Relative))); menuItem.Click += (object sender, RoutedEventArgs e) => { if (EditorCommon.MessageBox.Show($"即将删除{item.Name},删除后无法恢复,是否继续?", EditorCommon.MessageBox.enMessageBoxButton.YesNo) == EditorCommon.MessageBox.enMessageBoxResult.Yes) { item.ParentCategory.Items.Remove(item); ctrl.RemoveNodesContainer(item); var fileName = ctrl.GetGraphFileName(item.Name); EngineNS.CEngine.Instance.FileManager.DeleteFile(fileName); // 从UIResourceInfo中删除Event标记 var key = new UIResourceInfo.UIEventDicKey(initData.UIElementId, initData.FunctionName); HostControl.CurrentResInfo.UIEventsDic.Remove(key); } }; item.CategoryItemContextMenu.Items.Add(menuItem); } })); Macross.CategoryItem.RegistInitAction("UI_UIElement_PropertyCustomBind", new Action <Macross.CategoryItem, Macross.IMacrossOperationContainer, Macross.CategoryItem.InitializeData>((item, ctrl, data) => { var initData = data as UIElementPropertyCustomBindCategoryitemInitData; item.Icon = TryFindResource("Icon_Function") as ImageSource; item.Name = initData.FunctionName; item.ShowName = $"UIBindFunc_{initData.PropertyName}({initData.UIElement.Initializer.Name})"; Macross.CategoryItem.Delegate_OnDoubleClick action = async(categoryItem) => { var noUse = await ctrl.ShowNodesContainer(categoryItem); }; item.OnDoubleClick += action; if (item.PropertyShowItem == null) { item.PropertyShowItem = new UIElementPropertyCustomBindCategoryItemPropertys(); } BindingOperations.SetBinding(item, Macross.CategoryItem.NameProperty, new Binding("FunctionName") { Source = initData }); var varItemPro = item.PropertyShowItem as UIElementPropertyCustomBindCategoryItemPropertys; varItemPro.MethodInfo.MethodName = item.Name; varItemPro.MethodInfo.DisplayName = item.ShowName; BindingOperations.SetBinding(varItemPro.MethodInfo, CodeDomNode.CustomMethodInfo.MethodNameProperty, new Binding("Name") { Source = item }); initData.UIElement.Initializer.PropertyChanged += (sender, e) => { switch (e.PropertyName) { case "Name": item.ShowName = $"UIBindFuc_{initData.PropertyName}({initData.UIElement.Initializer.Name})"; varItemPro.MethodInfo.DisplayName = item.ShowName; break; } }; var funcParam = new CodeDomNode.CustomMethodInfo.FunctionParam(); funcParam.HostMethodInfo = varItemPro.MethodInfo; funcParam.ParamName = "uiElement"; funcParam.ParamType = new CodeDomNode.VariableType(initData.UIElement.GetType(), ctrl.CSType); varItemPro.MethodInfo.InParams.Add(funcParam); funcParam = new CodeDomNode.CustomMethodInfo.FunctionParam(); funcParam.HostMethodInfo = varItemPro.MethodInfo; funcParam.ParamName = "value"; funcParam.ParamType = new CodeDomNode.VariableType(initData.PropertyType, ctrl.CSType); varItemPro.MethodInfo.InParams.Add(funcParam); var menuItem = new MenuItem() { Name = "UIElementPropertyCustomBindFuncOpenGraph", Header = "打开", Style = TryFindResource(new ComponentResourceKey(typeof(ResourceLibrary.CustomResources), "MenuItem_Default")) as Style, }; menuItem.Click += (object sender, RoutedEventArgs e) => { action.Invoke(item); }; })); Macross.CategoryItem.RegistInitAction("UI_UIElement_VariableBind", new Action <Macross.CategoryItem, Macross.IMacrossOperationContainer, Macross.CategoryItem.InitializeData>((item, ctrl, data) => { var initData = data as UIElementVariableBindCategoryItemInitData; item.Icon = TryFindResource("Icon_Function") as ImageSource; item.Name = initData.FunctionName; item.ShowName = $"UIVarBind_({initData.TargetUIElement.Initializer.Name}.{initData.TargetPropertyName})"; Macross.CategoryItem.Delegate_OnDoubleClick action = async(categoryItem) => { var noUse = await ctrl.ShowNodesContainer(categoryItem); }; item.OnDoubleClick += action; if (item.PropertyShowItem == null) { item.PropertyShowItem = new UIElementVariableBindCategoryItemPropertys(); } BindingOperations.SetBinding(item, Macross.CategoryItem.NameProperty, new Binding("FunctionName") { Source = initData }); var varItemPro = item.PropertyShowItem as UIElementVariableBindCategoryItemPropertys; varItemPro.MethodInfo.MethodName = item.Name; varItemPro.MethodInfo.DisplayName = item.ShowName; BindingOperations.SetBinding(varItemPro.MethodInfo, CodeDomNode.CustomMethodInfo.MethodNameProperty, new Binding("Name") { Source = item }); initData.TargetUIElement.Initializer.PropertyChanged += (sender, e) => { switch (e.PropertyName) { case "Name": item.ShowName = $"UIVarBind_({initData.TargetUIElement.Initializer.Name}.{initData.TargetPropertyName})"; varItemPro.MethodInfo.DisplayName = item.ShowName; break; } }; var funcParam = new CodeDomNode.CustomMethodInfo.FunctionParam(); funcParam.HostMethodInfo = varItemPro.MethodInfo; funcParam.ParamName = "uiElement"; funcParam.ParamType = new CodeDomNode.VariableType(initData.UIElement.GetType(), ctrl.CSType); varItemPro.MethodInfo.InParams.Add(funcParam); funcParam = new CodeDomNode.CustomMethodInfo.FunctionParam(); funcParam.HostMethodInfo = varItemPro.MethodInfo; funcParam.ParamName = "inValue"; funcParam.ParamType = new CodeDomNode.VariableType(initData.PropertyType, ctrl.CSType); varItemPro.MethodInfo.InParams.Add(funcParam); var retParam = new CodeDomNode.CustomMethodInfo.FunctionParam(); retParam.HostMethodInfo = varItemPro.MethodInfo; retParam.ParamName = "outValue"; retParam.ParamType = new CodeDomNode.VariableType(initData.TargetPropertyType, ctrl.CSType); varItemPro.MethodInfo.OutParams.Add(retParam); var menuItem = new MenuItem() { Name = "UIElementVariableBindFuncOpenGraph", Header = "打开", Style = TryFindResource(new ComponentResourceKey(typeof(ResourceLibrary.CustomResources), "MenuItem_Default")) as Style, }; ResourceLibrary.Controls.Menu.MenuAssist.SetIcon(menuItem, new BitmapImage(new Uri("/ResourceLibrary;component/Icons/Icons/icon_Edit_Delete_40x.png", UriKind.Relative))); menuItem.Click += (object sender, RoutedEventArgs e) => { action.Invoke(item); }; })); Macross.CategoryItem.RegistInitAction("UI_UIElement_CustomEvent", new Action <Macross.CategoryItem, Macross.IMacrossOperationContainer, Macross.CategoryItem.InitializeData>((item, ctrl, data) => { var initData = data as UIElementCustomEventCategoryItemInitData; item.Icon = TryFindResource("Icon_Function") as ImageSource; item.Name = initData.DisplayName; if (item.PropertyShowItem == null) { item.PropertyShowItem = new UIElementCustomEventCategoryItemPropertys(); } var itemPro = item.PropertyShowItem as UIElementCustomEventCategoryItemPropertys; itemPro.Name = initData.DisplayName; itemPro.MethodInfo.MethodName = initData.EventName; itemPro.MethodInfo.DisplayName = initData.DisplayName; itemPro.MethodInfo.CSType = ctrl.CSType; itemPro.MethodInfo.IsDelegateEvent = true; BindingOperations.SetBinding(item, Macross.CategoryItem.NameProperty, new Binding("DisplayName") { Source = itemPro.MethodInfo, Mode = BindingMode.TwoWay }); BindingOperations.SetBinding(itemPro, UIElementCustomEventCategoryItemPropertys.NameProperty, new Binding("Name") { Source = item, Mode = BindingMode.TwoWay }); BindingOperations.SetBinding(itemPro.MethodInfo, CodeDomNode.CustomMethodInfo.TooltipProperty, new Binding("ToolTips") { Source = item, Mode = BindingMode.TwoWay }); item.OnNameChangedEvent += async(categoryItem, newValue, oldValue) => { foreach (var insData in categoryItem.InstanceNodes) { var container = await categoryItem.ParentCategory.HostControl.HostControl.GetNodesContainer(insData.ContainerKeyId, true); var node = container.FindControl(insData.NodeId); var param = node.CSParam as CodeDomNode.MethodCustomInvoke.MethodCustomInvokeConstructParam; param.MethodInfo.DisplayName = newValue; } }; item.OnDropToNodesControlAction = (dropData) => { var nodeCtrl = EditorCommon.Program.GetParent(dropData.DropCanvas, typeof(CodeGenerateSystem.Controls.NodesContainerControl)) as CodeGenerateSystem.Controls.NodesContainerControl; var nodeType = typeof(CodeDomNode.MethodCustomInvoke); var csParam = new CodeDomNode.MethodCustomInvoke.MethodCustomInvokeConstructParam(); csParam.CSType = ctrl.CSType; csParam.HostNodesContainer = nodeCtrl; csParam.ConstructParam = ""; csParam.MethodInfo = itemPro.MethodInfo; var pos = nodeCtrl._RectCanvas.TranslatePoint(dropData.DropPos, nodeCtrl._MainDrawCanvas); var node = nodeCtrl.AddNodeControl(nodeType, csParam, pos.X, pos.Y); node.NodeNameAddShowNodeName = false; item.AddInstanceNode(nodeCtrl.GUID, node); }; var menuItem = new MenuItem() { Name = "UI_CustomEvent_Delete", Header = "删除", Style = TryFindResource(new ComponentResourceKey(typeof(ResourceLibrary.CustomResources), "MenuItem_Default")) as Style, }; ResourceLibrary.Controls.Menu.MenuAssist.SetIcon(menuItem, new BitmapImage(new Uri("/ResourceLibrary;component/Icons/Icons/icon_Edit_Delete_40x.png", UriKind.Relative))); menuItem.Click += (object sender, RoutedEventArgs e) => { if (EditorCommon.MessageBox.Show($"即将删除{this.Name},删除后无法恢复,是否继续?", EditorCommon.MessageBox.enMessageBoxButton.YesNo) == EditorCommon.MessageBox.enMessageBoxResult.Yes) { item.RemoveFromParent(); ctrl.RemoveNodesContainer(item); var fileName = ctrl.GetGraphFileName(this.Name); EngineNS.CEngine.Instance.FileManager.DeleteFile(fileName); item.ParentCategory?.HostControl.HostControl.ShowItemPropertys(null); } }; item.CategoryItemContextMenu.Items.Add(menuItem); })); }