/// <summary>Adds a context menu to a TreeNode control</summary> /// <param name="node">TreeNode where to add the context menu</param> /// <param name="form">Current application form</param> public static void AddContextMenu(TreeNode node, FetchXmlBuilder form) { form.addMenu.Items.Clear(); var nodecapabilities = new FetchNodeCapabilities(node); foreach (var childcapability in nodecapabilities.ChildTypes) { if (childcapability.Name == "-") { form.addMenu.Items.Add(new ToolStripSeparator()); } else if (childcapability.Multiple || !node.Nodes.ContainsKey(childcapability.Name)) { var additem = form.addMenu.Items.Add(childcapability.Name); additem.Tag = childcapability.Name; } } if (form.addMenu.Items.Count == 0) { var dummy = form.addMenu.Items.Add("nothing to add"); dummy.Enabled = false; } form.selectAttributesToolStripMenuItem.Visible = nodecapabilities.Attributes; form.deleteToolStripMenuItem.Enabled = nodecapabilities.Delete; form.commentToolStripMenuItem.Enabled = nodecapabilities.Comment; form.uncommentToolStripMenuItem.Enabled = nodecapabilities.Uncomment; node.ContextMenuStrip = form.nodeMenu; }
/// <summary> /// Adds a new TreeNode to the parent object from the XmlNode information /// </summary> /// <param name="parentObject">Object (TreeNode or TreeView) where to add a new TreeNode</param> /// <param name="xmlNode">Xml node from the sitemap</param> /// <param name="form">Current application form</param> /// <param name="isDisabled"> </param> public static TreeNode AddTreeViewNode(object parentObject, XmlNode xmlNode, FetchXmlBuilder form, int index = -1) { TreeNode node = null; if (xmlNode is XmlElement || xmlNode is XmlComment) { node = new TreeNode(xmlNode.Name); node.Name = xmlNode.Name; Dictionary<string, string> attributes = new Dictionary<string, string>(); if (xmlNode.NodeType == XmlNodeType.Comment) { attributes.Add("#comment", xmlNode.Value); node.ForeColor = System.Drawing.Color.Gray; } else if (xmlNode.Attributes != null) { foreach (XmlAttribute attr in xmlNode.Attributes) { attributes.Add(attr.Name, attr.Value); } } if (parentObject is TreeView) { ((TreeView)parentObject).Nodes.Add(node); } else if (parentObject is TreeNode) { if (index == -1) { ((TreeNode)parentObject).Nodes.Add(node); } else { ((TreeNode)parentObject).Nodes.Insert(index, node); } } else { throw new Exception("AddTreeViewNode: Unsupported control type"); } node.Tag = attributes; AddContextMenu(node, form); foreach (XmlNode childNode in xmlNode.ChildNodes) { AddTreeViewNode(node, childNode, form); } SetNodeText(node, FetchXmlBuilder.friendlyNames); } else if (xmlNode is XmlText && parentObject is TreeNode) { var treeNode = (TreeNode)parentObject; if (treeNode.Tag is Dictionary<string, string>) { var attributes = (Dictionary<string, string>)treeNode.Tag; attributes.Add("#text", ((XmlText)xmlNode).Value); } } return node; }
public filterControl(Dictionary<string, string> collection, FetchXmlBuilder fetchXmlBuilder) : this() { if (collection != null) collec = collection; ControlUtils.FillControls(collec, this.Controls); controlsCheckSum = ControlUtils.ControlsChecksum(this.Controls); Saved += fetchXmlBuilder.CtrlSaved; }
public entityControl(Dictionary<string, string> collection, FetchXmlBuilder fetchXmlBuilder) : this() { fxb = fetchXmlBuilder; if (collection != null) collec = collection; PopulateControls(); ControlUtils.FillControls(collec, this.Controls); controlsCheckSum = ControlUtils.ControlsChecksum(this.Controls); Saved += fetchXmlBuilder.CtrlSaved; }
public attributeControl(TreeNode Node, AttributeMetadata[] attributes, FetchXmlBuilder fetchXmlBuilder) : this() { collec = (Dictionary<string, string>)Node.Tag; if (collec == null) { collec = new Dictionary<string, string>(); } node = Node; PopulateControls(Node, attributes); ControlUtils.FillControls(collec, this.Controls); controlsCheckSum = ControlUtils.ControlsChecksum(this.Controls); Saved += fetchXmlBuilder.CtrlSaved; }
public linkEntityControl(TreeNode Node, FetchXmlBuilder fetchXmlBuilder) : this() { form = fetchXmlBuilder; node = Node; collec = (Dictionary<string, string>)node.Tag; if (collec == null) { collec = new Dictionary<string, string>(); } PopulateControls(); ControlUtils.FillControls(collec, this.Controls); controlsCheckSum = ControlUtils.ControlsChecksum(this.Controls); Saved += fetchXmlBuilder.CtrlSaved; }
/// <summary> /// Adds a new TreeNode to the parent object from the XmlNode information /// </summary> /// <param name="parentObject">Object (TreeNode or TreeView) where to add a new TreeNode</param> /// <param name="xmlNode">Xml node from the sitemap</param> /// <param name="form">Current application form</param> /// <param name="isDisabled"> </param> public static void AddTreeViewNode(object parentObject, XmlNode xmlNode, FetchXmlBuilder form, bool isDisabled = false) { if (xmlNode is XmlElement) { TreeNode node = new TreeNode(xmlNode.Name); node.Name = xmlNode.Name; Dictionary<string, string> attributes = new Dictionary<string, string>(); if (xmlNode.Attributes != null) { foreach (XmlAttribute attr in xmlNode.Attributes) { attributes.Add(attr.Name, attr.Value); } } if (parentObject is TreeView) { ((TreeView)parentObject).Nodes.Add(node); } else if (parentObject is TreeNode) { ((TreeNode)parentObject).Nodes.Add(node); } else { throw new Exception("AddTreeViewNode: Unsupported control type"); } node.Tag = attributes; AddContextMenu(node, form); foreach (XmlNode childNode in xmlNode.ChildNodes) { if (childNode.NodeType != XmlNodeType.Comment) { AddTreeViewNode(node, childNode, form); } } SetNodeText(node); } else if (xmlNode is XmlText && parentObject is TreeNode) { var treeNode = (TreeNode)parentObject; if (treeNode.Tag is Dictionary<string, string>) { var attributes = (Dictionary<string, string>)treeNode.Tag; attributes.Add("#text", ((XmlText)xmlNode).Value); } } }
public orderControl(TreeNode Node, AttributeMetadata[] attributes, FetchXmlBuilder fetchXmlBuilder) : this() { form = fetchXmlBuilder; friendly = fetchXmlBuilder.currentSettings.useFriendlyNames; collec = (Dictionary<string, string>)Node.Tag; if (collec == null) { collec = new Dictionary<string, string>(); } PopulateControls(Node, attributes); ControlUtils.FillControls(collec, this.Controls); controlsCheckSum = ControlUtils.ControlsChecksum(this.Controls); Saved += fetchXmlBuilder.CtrlSaved; }
public SelectViewDialog(FetchXmlBuilder caller) { InitializeComponent(); Caller = caller; cmbEntity.Items.Clear(); var entities = FetchXmlBuilder.GetDisplayEntities(); if (entities != null) { foreach (var entity in entities) { if (entity.Value.IsIntersect != true && FetchXmlBuilder.views.ContainsKey(entity.Value.LogicalName + "|S")) { cmbEntity.Items.Add(new EntityItem(entity.Value)); } } } }
public ResultGrid(EntityCollection Entities, FetchXmlBuilder fetchXmlBuilder) { InitializeComponent(); entities = Entities; form = fetchXmlBuilder; var size = form.currentSettings.gridWinSize; if (size != null && size.Width > 0 && size.Height > 0) { Width = size.Width; Height = size.Height; ; } if (form.currentSettings.gridFriendly) { // This pretty stupid if/else because setting the Friendly flag will trigger RefreshAll, and we don't want it twice. chkFriendly.Checked = true; } else { RefreshAll(); } }
public static string GetODataQuery(FetchType fetch, string organizationServiceUrl, FetchXmlBuilder sender) { if (sender.Service == null) { throw new Exception("Must have an active connection to CRM to compose OData query."); } var url = organizationServiceUrl; var entity = fetch.Items.Where(i => i is FetchEntityType).FirstOrDefault() as FetchEntityType; if (entity == null) { throw new Exception("Fetch must contain entity definition"); } url += "/" + LogicalToSchemaName(entity.name, sender) + "Set"; var query = ""; if (!string.IsNullOrEmpty(fetch.top)) { query = AppendQuery(query, "$top", fetch.top); } if (entity.Items != null) { var select = GetSelect(entity, sender); var order = GetOrder(entity, sender); var expand = GetExpand(entity, sender, ref select); var filter = GetFilter(entity, sender); query = AppendQuery(query, "$select", select); query = AppendQuery(query, "$orderby", order); query = AppendQuery(query, "$expand", expand); query = AppendQuery(query, "$filter", filter); } if (!string.IsNullOrEmpty(query)) { url += "?" + query; } return url; }
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { FetchXmlBuilder.OpenURL("https://fetchxmlbuilder.com"); }
public linkEntityControl(TreeNode node, FetchXmlBuilder fetchXmlBuilder, TreeBuilderControl tree) { InitializeComponent(); InitializeFXB(null, fetchXmlBuilder, tree, node); }
private static string LogicalToSchemaName(string entity, string attribute, FetchXmlBuilder sender) { GetEntityMetadata(entity, sender); var attrMeta = FetchXmlBuilder.GetAttribute(entity, attribute); if (attrMeta == null) { throw new Exception($"No metadata for attribute: {entity}.{attribute}"); } return attrMeta.SchemaName; }
private static string GetFilter(string entityname, string entityalias, filter filteritem, FetchXmlBuilder fxb) { var result = ""; if (filteritem.Items == null || filteritem.Items.Length == 0) { return(""); } var logical = filteritem.type == filterType.or ? " OR " : " AND "; if (filteritem.Items.Length > 1) { result = "("; } foreach (var item in filteritem.Items) { if (item is condition) { result += GetCondition(entityname, entityalias, item as condition, fxb); } else if (item is filter) { result += GetFilter(entityname, entityalias, item as filter, fxb); } result += logical; } if (result.EndsWith(logical)) { result = result.Substring(0, result.Length - logical.Length); } if (filteritem.Items.Length > 1) { result += ")"; } return(result); }
private static string GetOrder(FetchEntityType entity, FetchXmlBuilder sender) { var result = ""; var orderitems = entity.Items.Where(i => i is FetchOrderType && ((FetchOrderType)i).attribute != null).ToList(); if (orderitems.Count > 0) { foreach (FetchOrderType orderitem in orderitems) { result += LogicalToSchemaName(entity.name, orderitem.attribute, sender); if (orderitem.descending) { result += " desc"; } result += ","; } } return result; }
private static RelationshipMetadataBase LinkItemToRelation(string entityname, FetchLinkEntityType linkitem, FetchXmlBuilder sender) { GetEntityMetadata(entityname, sender); var entity = FetchXmlBuilder.entities[entityname]; foreach (var relation in entity.OneToManyRelationships) { if (relation.ReferencedEntity == entityname && relation.ReferencedAttribute == linkitem.to && relation.ReferencingEntity == linkitem.name && relation.ReferencingAttribute == linkitem.from) { return relation; } } foreach (var relation in entity.ManyToOneRelationships) { if (relation.ReferencingEntity == entityname && relation.ReferencingAttribute == linkitem.to && relation.ReferencedEntity == linkitem.name && relation.ReferencedAttribute == linkitem.from) { return relation; } } foreach (var relation in entity.ManyToManyRelationships) { if (relation.Entity1LogicalName == entityname && relation.Entity1IntersectAttribute == linkitem.from) { var linkitems = linkitem.Items.Where(i => i is FetchLinkEntityType).ToList(); if (linkitems.Count > 1) { throw new Exception("Invalid M:M-relation definition for OData"); } if (linkitems.Count == 1) { var nextlink = (FetchLinkEntityType)linkitems[0]; if (nextlink.linktype == "outer") { throw new Exception("OData queries do not support outer joins"); } if (relation.Entity2LogicalName == nextlink.name && relation.Entity2IntersectAttribute == nextlink.to) { return relation; } } } if (relation.Entity2LogicalName == entityname && relation.Entity2IntersectAttribute == linkitem.from) { var linkitems = linkitem.Items.Where(i => i is FetchLinkEntityType).ToList(); if (linkitems.Count > 1) { throw new Exception("Invalid M:M-relation definition for OData"); } if (linkitems.Count == 1) { var nextlink = (FetchLinkEntityType)linkitems[0]; if (nextlink.linktype == "outer") { throw new Exception("OData queries do not support outer joins"); } if (relation.Entity1LogicalName == nextlink.name && relation.Entity1IntersectAttribute == nextlink.to) { return relation; } } } } throw new Exception($"Cannot find metadata for relation {entityname}.{linkitem.to} => {linkitem.name}.{linkitem.from}"); }
private static string GetCondition(string entityName, condition condition, FetchXmlBuilder sender) { var result = ""; if (!string.IsNullOrEmpty(condition.attribute)) { if (!String.IsNullOrEmpty(condition.entityname)) { throw new ApplicationException($"OData queries do not support filtering on link entities. If filtering on the primary key of an N:1 related entity, please add the filter to the link entity itself"); } GetEntityMetadata(entityName, sender); var attrMeta = sender.GetAttribute(entityName, condition.attribute); if (attrMeta == null) { throw new Exception($"No metadata for attribute: {entityName}.{condition.attribute}"); } result = GetPropertyName(attrMeta); string function = null; var functionParameters = 1; var functionParameterType = typeof(string); switch (condition.@operator) { case @operator.eq: case @operator.ne: case @operator.lt: case @operator.le: case @operator.gt: case @operator.ge: result += $" {condition.@operator} "; break; case @operator.neq: result += " ne "; break; case @operator.@null: result += " eq null"; break; case @operator.notnull: result += " ne null"; break; case @operator.like: result = $"contains({attrMeta.LogicalName}, '{condition.value}')"; break; case @operator.notlike: result = $"not contains({attrMeta.LogicalName}, '{condition.value}')"; break; case @operator.beginswith: result = $"startswith({attrMeta.LogicalName}, '{condition.value}')"; break; case @operator.endswith: result = $"endswith({attrMeta.LogicalName}, '{condition.value}')"; break; case @operator.above: function = "Above"; break; case @operator.eqorabove: function = "AboveOrEqual"; break; case @operator.between: function = "Between"; functionParameters = Int32.MaxValue; break; case @operator.containvalues: function = "ContainsValues"; functionParameters = Int32.MaxValue; break; case @operator.notcontainvalues: function = "DoesNotContainValues"; functionParameters = Int32.MaxValue; break; case @operator.eqbusinessid: function = "EqualBusinessId"; functionParameters = 0; break; case @operator.equserid: function = "EqualUserId"; functionParameters = 0; break; case @operator.equserlanguage: function = "EqualUserLanguage"; functionParameters = 0; break; case @operator.equseroruserhierarchy: function = "EqualUserOrUserHierarchy"; functionParameters = 0; break; case @operator.equseroruserhierarchyandteams: function = "EqualUserOrUserHierarchyAndTeams"; functionParameters = 0; break; case @operator.equseroruserteams: function = "EqualUserOrUserTeams"; functionParameters = 0; break; case @operator.equserteams: function = "EqualUserTeams"; functionParameters = 0; break; case @operator.@in: function = "In"; functionParameters = Int32.MaxValue; break; case @operator.infiscalperiod: function = "InFiscalPeriod"; functionParameterType = typeof(long); break; case @operator.infiscalperiodandyear: function = "InFiscalPeriodAndYear"; functionParameters = 2; functionParameterType = typeof(long); break; case @operator.infiscalyear: function = "InFiscalYear"; functionParameterType = typeof(long); break; case @operator.inorafterfiscalperiodandyear: function = "InOrAfterFiscalPeriodAndYear"; functionParameters = 2; functionParameterType = typeof(long); break; case @operator.inorbeforefiscalperiodandyear: function = "InOrBeforeFiscalPeriodAndYear"; functionParameters = 2; functionParameterType = typeof(long); break; case @operator.lastsevendays: function = "Last7Days"; functionParameters = 0; break; case @operator.lastfiscalperiod: function = "LastFiscalPeriod"; functionParameters = 0; break; case @operator.lastfiscalyear: function = "LastFiscalYear"; functionParameters = 0; break; case @operator.lastmonth: function = "LastMonth"; functionParameters = 0; break; case @operator.lastweek: function = "LastWeek"; functionParameters = 0; break; case @operator.lastxdays: function = "LastXDays"; functionParameterType = typeof(long); break; case @operator.lastxfiscalperiods: function = "LastXFiscalPeriods"; functionParameterType = typeof(long); break; case @operator.lastxfiscalyears: function = "LastXFiscalYears"; functionParameterType = typeof(long); break; case @operator.lastxhours: function = "LastXHours"; functionParameterType = typeof(long); break; case @operator.lastxmonths: function = "LastXMonths"; functionParameterType = typeof(long); break; case @operator.lastxweeks: function = "LastXWeeks"; functionParameterType = typeof(long); break; case @operator.lastxyears: function = "LastXYears"; functionParameterType = typeof(long); break; case @operator.lastyear: function = "LastYear"; functionParameters = 0; break; case @operator.nextsevendays: function = "Next7Days"; functionParameters = 0; break; case @operator.nextfiscalperiod: function = "NextFiscalPeriod"; functionParameters = 0; break; case @operator.nextfiscalyear: function = "NextFiscalYear"; functionParameters = 0; break; case @operator.nextmonth: function = "NextMonth"; functionParameters = 0; break; case @operator.nextweek: function = "NextWeek"; functionParameters = 0; break; case @operator.nextxdays: function = "NextXDays"; functionParameterType = typeof(long); break; case @operator.nextxfiscalperiods: function = "NextXFiscalPeriods"; functionParameterType = typeof(long); break; case @operator.nextxfiscalyears: function = "NextXFiscalYears"; functionParameterType = typeof(long); break; case @operator.nextxhours: function = "NextXHours"; functionParameterType = typeof(long); break; case @operator.nextxmonths: function = "NextXMonths"; functionParameterType = typeof(long); break; case @operator.nextxweeks: function = "NextXWeeks"; functionParameterType = typeof(long); break; case @operator.nextxyears: function = "NextXYears"; functionParameterType = typeof(long); break; case @operator.nextyear: function = "NextYear"; functionParameters = 0; break; case @operator.notbetween: function = "NotBetween"; functionParameters = Int32.MaxValue; break; case @operator.nebusinessid: function = "NotEqualBusinessId"; functionParameters = 0; break; case @operator.neuserid: function = "NotEqualUserId"; functionParameters = 0; break; case @operator.notin: function = "NotIn"; functionParameters = Int32.MaxValue; break; case @operator.notunder: function = "NotUnder"; break; case @operator.olderthanxdays: function = "OlderThanXDays"; functionParameterType = typeof(long); break; case @operator.olderthanxhours: function = "OlderThanXHours"; functionParameterType = typeof(long); break; case @operator.olderthanxminutes: function = "OlderThanXMinutes"; functionParameterType = typeof(long); break; case @operator.olderthanxmonths: function = "OlderThanXMonths"; functionParameterType = typeof(long); break; case @operator.olderthanxweeks: function = "OlderThanXWeeks"; functionParameterType = typeof(long); break; case @operator.olderthanxyears: function = "OlderThanXYears"; functionParameterType = typeof(long); break; case @operator.on: function = "On"; break; case @operator.onorafter: function = "OnOrAfter"; break; case @operator.onorbefore: function = "OnOrBefore"; break; case @operator.thisfiscalperiod: function = "ThisFiscalPeriod"; functionParameters = 0; break; case @operator.thisfiscalyear: function = "ThisFiscalYear"; functionParameters = 0; break; case @operator.thismonth: function = "ThisMonth"; functionParameters = 0; break; case @operator.thisweek: function = "ThisWeek"; functionParameters = 0; break; case @operator.thisyear: function = "ThisYear"; functionParameters = 0; break; case @operator.today: function = "Today"; functionParameters = 0; break; case @operator.tomorrow: function = "Tomorrow"; functionParameters = 0; break; case @operator.under: function = "Under"; break; case @operator.eqorunder: function = "UnderOrEqual"; break; case @operator.yesterday: function = "Yesterday"; functionParameters = 0; break; default: throw new Exception($"Unsupported OData condition operator '{condition.@operator}'"); } if (!String.IsNullOrEmpty(function)) { if (functionParameters == Int32.MaxValue) { return($"Microsoft.Dynamics.CRM.{function}(PropertyName='{attrMeta.LogicalName}',PropertyValues=[{String.Join(",", condition.Items.Select(i => FormatValue(functionParameterType, i.Value)))}])"); } else if (functionParameters == 0) { return($"Microsoft.Dynamics.CRM.{function}(PropertyName='{attrMeta.LogicalName}')"); } else if (functionParameters == 1) { return($"Microsoft.Dynamics.CRM.{function}(PropertyName='{attrMeta.LogicalName}',PropertyValue={FormatValue(functionParameterType, condition.value)})"); } else { return($"Microsoft.Dynamics.CRM.{function}(PropertyName='{attrMeta.LogicalName}',{String.Join(",", condition.Items.Select((i, idx) => $"Property{idx + 1}={FormatValue(functionParameterType, i.Value)}"))})"); } } if (!string.IsNullOrEmpty(condition.value) && !result.Contains("(")) { var valueType = typeof(string); switch (attrMeta.AttributeType) { case AttributeTypeCode.Money: case AttributeTypeCode.Decimal: valueType = typeof(decimal); break; case AttributeTypeCode.BigInt: valueType = typeof(long); break; case AttributeTypeCode.Boolean: valueType = typeof(bool); break; case AttributeTypeCode.Double: valueType = typeof(double); break; case AttributeTypeCode.Integer: case AttributeTypeCode.State: case AttributeTypeCode.Status: case AttributeTypeCode.Picklist: valueType = typeof(int); break; case AttributeTypeCode.Uniqueidentifier: case AttributeTypeCode.Lookup: case AttributeTypeCode.Customer: case AttributeTypeCode.Owner: valueType = typeof(Guid); break; case AttributeTypeCode.DateTime: valueType = typeof(DateTime); break; } result += FormatValue(valueType, condition.value); } } return(result); }
private static string GetFilter(FetchEntityType entity, FetchXmlBuilder sender) { var result = ""; var filteritems = entity.Items.Where(i => i is filter && ((filter)i).Items != null && ((filter)i).Items.Length > 0).ToList(); if (filteritems.Count > 0) { foreach (filter filteritem in filteritems) { result += GetFilter(entity, filteritem, sender); } if (result.StartsWith("(") && result.EndsWith(")")) { result = result.Substring(1, result.Length - 2); } } return result; }
public static string GetOData4Query(FetchType fetch, string organizationServiceUrl, FetchXmlBuilder sender) { if (sender.Service == null) { throw new Exception("Must have an active connection to CRM to compose OData query."); } var url = organizationServiceUrl; var entity = fetch.Items.Where(i => i is FetchEntityType).FirstOrDefault() as FetchEntityType; if (entity == null) { throw new Exception("Fetch must contain entity definition"); } url += "/" + LogicalToCollectionName(entity.name, sender); var query = ""; if (!string.IsNullOrEmpty(fetch.top)) { query = AppendQuery(query, "$top", fetch.top); } if (entity.Items != null) { if (fetch.aggregate) { var aggregate = GetAggregate(entity, sender); var filter = GetFilter(entity, sender, null); var apply = aggregate; if (!String.IsNullOrEmpty(filter)) { apply = $"filter({filter})/{aggregate}"; } query = AppendQuery(query, "$apply", apply); } else { var select = GetSelect(entity, sender); var order = GetOrder(entity, sender); var expandFilter = ""; var expand = GetExpand(entity, sender, ref expandFilter); var filter = GetFilter(entity, sender, expandFilter); query = AppendQuery(query, "$select", select); query = AppendQuery(query, "$orderby", order); query = AppendQuery(query, "$expand", expand); query = AppendQuery(query, "$filter", filter); } } if (!string.IsNullOrEmpty(query)) { url += "?" + query; } return(url); }
private static string GetExpand(FetchEntityType entity, FetchXmlBuilder sender, ref string filterString) { var resultList = new List <string>(); var linkitems = entity.Items.Where(i => i is FetchLinkEntityType).ToList(); if (linkitems.Count > 0) { foreach (FetchLinkEntityType linkitem in linkitems) { var navigationProperty = LinkItemToNavigationProperty(entity.name, linkitem, sender, out var child); if (linkitem.Items != null) { if (!linkitem.intersect && linkitem.Items.Where(i => i is FetchLinkEntityType).ToList().Count > 0) { throw new Exception("OData queries only support one level of link entities"); } if (!child) { if (linkitem.Items.Where(i => i is filter).ToList().Count > 0) { foreach (var filter in linkitem.Items.OfType <filter>()) { foreach (var condition in filter.Items.OfType <condition>()) { var targetLogicalName = linkitem.name; GetEntityMetadata(targetLogicalName, sender); if (condition.attribute == sender.entities[targetLogicalName].PrimaryIdAttribute) { if (!String.IsNullOrEmpty(filterString)) { filterString += $" {filter.type} "; } filterString += navigationProperty + "/" + GetCondition(linkitem.name, condition, sender); } else { throw new Exception($"OData queries do not support filter on link entities except by primary key. Filter on {linkitem.name}.{condition.attribute} is not allowed"); } } } } if (linkitem.Items.Where(i => i is FetchOrderType).ToList().Count > 0) { throw new Exception("OData queries do not support sorting on parent link entities"); } } } var expandedSelect = GetExpandedSelect(linkitem, sender); var childFilter = child ? linkitem.Items?.OfType <filter>().FirstOrDefault() : null; var expandedFilter = childFilter == null ? null : GetFilter(linkitem.name, childFilter, sender); var childOrders = child ? linkitem.Items?.OfType <FetchOrderType>().ToList() : null; var expandedOrder = childOrders == null ? null : GetOrder(linkitem.name, sender, childOrders); if (String.IsNullOrEmpty(expandedSelect) && String.IsNullOrEmpty(expandedFilter) && String.IsNullOrEmpty(expandedOrder)) { resultList.Add(navigationProperty); } else { var options = new List <string>(); if (!String.IsNullOrEmpty(expandedSelect)) { options.Add("$select=" + expandedSelect); } if (!String.IsNullOrEmpty(expandedFilter)) { options.Add("$filter=" + expandedFilter); } if (!String.IsNullOrEmpty(expandedOrder)) { options.Add("$orderby=" + expandedOrder); } resultList.Add(navigationProperty + "(" + String.Join(";", options) + ")"); } } } return(string.Join(",", resultList)); }
internal XmlContentControl(FetchXmlBuilder caller) : this(ContentType.FetchXML, SaveFormat.XML, caller) { }
private void linkLabel4_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { FetchXmlBuilder.OpenURL("http://twitter.com/FetchXMLBuilder"); }
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { FetchXmlBuilder.OpenURL("https://jonasr.app"); }
/// <summary>Adds a context menu to a TreeNode control</summary> /// <param name="node">TreeNode where to add the context menu</param> /// <param name="form">Current application form</param> public static void AddContextMenu(TreeNode node, FetchXmlBuilder form) { var collec = (Dictionary<string, string>)node.Tag; //HideAllContextMenuItems(form.nodeMenu); //form.deleteToolStripMenuItem.Visible = true; form.addMenu.Items.Clear(); var nodecapabilities = new FetchNodeCapabilities(node); foreach (var childcapability in nodecapabilities.ChildTypes) { if (childcapability.Name == "-") { form.addMenu.Items.Add(new ToolStripSeparator()); } else if (childcapability.Multiple || !node.Nodes.ContainsKey(childcapability.Name)) { var additem = form.addMenu.Items.Add(childcapability.Name); additem.Tag = childcapability.Name; } } if (form.addMenu.Items.Count == 0) { var dummy = form.addMenu.Items.Add("nothing to add"); dummy.Enabled = false; } var cutcopy = true; form.deleteToolStripMenuItem.Enabled = nodecapabilities.Delete; form.cutToolStripMenuItem.Enabled = cutcopy; form.copyToolStripMenuItem.Enabled = cutcopy; form.pasteToolStripMenuItem.Enabled = form.clipboard.IsValidForPaste(node); node.ContextMenuStrip = form.nodeMenu; }
private static string LinkItemToNavigationProperty(string entityname, FetchLinkEntityType linkitem, FetchXmlBuilder sender, out bool child) { GetEntityMetadata(entityname, sender); var entity = sender.entities[entityname]; foreach (var relation in entity.OneToManyRelationships .Where(r => r.ReferencedEntity == entityname && r.ReferencedAttribute == linkitem.to && r.ReferencingEntity == linkitem.name && r.ReferencingAttribute == linkitem.from)) { if (linkitem.linktype != "outer") { throw new ApplicationException($"OData queries do not support inner joins on 1:N relationships. Try changing link to {linkitem.name} to an outer join"); } child = true; return(relation.ReferencedEntityNavigationPropertyName); } foreach (var relation in entity.ManyToOneRelationships .Where(r => r.ReferencingEntity == entityname && r.ReferencingAttribute == linkitem.to && r.ReferencedEntity == linkitem.name && r.ReferencedAttribute == linkitem.from)) { // OData $expand is equivalent to an outer join. Replicate inner join behaviour by adding a not-null filter on primary key // of related record type if (linkitem.linktype != "outer") { if (linkitem.Items == null) { linkitem.Items = new object[0]; } var filter = linkitem.Items.OfType <filter>().FirstOrDefault(f => f.type == filterType.and); if (filter == null) { filter = new filter { type = filterType.and, Items = new object[0] }; var items = new List <object>(linkitem.Items); items.Add(filter); linkitem.Items = items.ToArray(); } GetEntityMetadata(linkitem.name, sender); var linkedEntity = sender.entities[linkitem.name]; var condition = filter.Items.OfType <condition>() .FirstOrDefault(c => c.attribute == linkedEntity.PrimaryIdAttribute && c.@operator == @operator.notnull); if (condition == null) { condition = new condition { attribute = linkedEntity.PrimaryIdAttribute, @operator = @operator.notnull }; var items = new List <object>(filter.Items); items.Add(condition); filter.Items = items.ToArray(); } } child = false; return(relation.ReferencingEntityNavigationPropertyName); } foreach (var relation in entity.ManyToManyRelationships .Where(r => r.Entity1LogicalName == entityname && r.Entity1IntersectAttribute == linkitem.from)) { var linkitems = linkitem.Items.Where(i => i is FetchLinkEntityType).ToList(); if (linkitems.Count > 1) { throw new Exception("Invalid M:M-relation definition for OData"); } if (linkitems.Count == 1) { var nextlink = (FetchLinkEntityType)linkitems[0]; if (nextlink.linktype != "outer") { throw new Exception($"OData queries do not support inner joins on N:N relationships. Try changing link to {nextlink.name} to an outer join"); } if (relation.Entity2LogicalName == nextlink.name && relation.Entity2IntersectAttribute == nextlink.to) { child = true; return(relation.Entity1NavigationPropertyName); } } } foreach (var relation in entity.ManyToManyRelationships .Where(r => r.Entity2LogicalName == entityname && r.Entity2IntersectAttribute == linkitem.from)) { var linkitems = linkitem.Items.Where(i => i is FetchLinkEntityType).ToList(); if (linkitems.Count > 1) { throw new Exception("Invalid M:M-relation definition for OData"); } if (linkitems.Count == 1) { var nextlink = (FetchLinkEntityType)linkitems[0]; if (nextlink.linktype != "outer") { throw new Exception($"OData queries do not support inner joins on N:N relationships. Try changing link to {nextlink.name} to an outer join"); } if (relation.Entity1LogicalName == nextlink.name && relation.Entity1IntersectAttribute == nextlink.from) { child = true; return(relation.Entity2NavigationPropertyName); } } } throw new Exception($"Cannot find metadata for relation {entityname}.{linkitem.to} => {linkitem.name}.{linkitem.from}"); }
public XmlContentDisplayDialog(string xmlString, string header, bool allowEdit, bool allowFormat, bool allowExecute, FetchXmlBuilder caller) { InitializeComponent(); fxb = caller; result = null; execute = false; if (fxb.currentSettings.xmlWinSize != null && fxb.currentSettings.xmlWinSize.Width > 0 && fxb.currentSettings.xmlWinSize.Height > 0) { Width = fxb.currentSettings.xmlWinSize.Width; Height = fxb.currentSettings.xmlWinSize.Height; } Text = string.IsNullOrEmpty(header) ? "FetchXML Builder" : header; panOk.Visible = allowEdit; if (!allowEdit) { btnCancel.Text = "Close"; } btnFormat.Visible = allowFormat; btnExecute.Visible = allowExecute; if (xmlString.Length > 100000) { var dlgresult = MessageBox.Show("Huge result, this may take a while!\n" + xmlString.Length.ToString() + " characters in the XML document.\n\nContinue?", "Huge result", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (dlgresult == DialogResult.No) { xmlString = ""; } } txtXML.Text = xmlString; FormatXML(true); }
private static IEnumerable <string> GetAttributeNames(string entityName, IEnumerable <FetchAttributeType> attributeitems, FetchXmlBuilder sender) { GetEntityMetadata(entityName, sender); var entityMeta = sender.entities[entityName]; foreach (FetchAttributeType attributeitem in attributeitems) { if (!String.IsNullOrEmpty(attributeitem.alias)) { throw new ApplicationException($"OData queries do not support aliasing columns except for aggregate queries"); } var attrMeta = entityMeta.Attributes.SingleOrDefault(a => a.LogicalName == attributeitem.name); if (attrMeta == null) { throw new ApplicationException($"Unknown attribute {entityName}.{attributeitem.name}"); } yield return(GetPropertyName(attrMeta)); } }
private static string GetFilter(FetchEntityType entity, filter filteritem, FetchXmlBuilder sender) { var result = ""; if (filteritem.Items == null || filteritem.Items.Length == 0) { return ""; } var logical = filteritem.type == filterType.or ? " or " : " and "; if (filteritem.Items.Length > 1) { result = "("; } foreach (var item in filteritem.Items) { if (item is condition) { result += GetCondition(entity, item as condition, sender); } else if (item is filter) { result += GetFilter(entity, item as filter, sender); } result += logical; } if (result.EndsWith(logical)) { result = result.Substring(0, result.Length - logical.Length); } if (filteritem.Items.Length > 1) { result += ")"; } return result; }
private static string GetCondition(string entityname, string entityalias, condition condition) { var result = new StringBuilder(); if (!string.IsNullOrEmpty(entityalias)) { result.Append(entityalias); result.Append("."); } if (!string.IsNullOrEmpty(condition.attribute)) { if (!string.IsNullOrEmpty(condition.entityname)) { result.Append($"{condition.entityname}."); if (aliasmap.ContainsKey(condition.entityname)) { entityname = aliasmap[condition.entityname]; } else { entityname = condition.entityname; } } result.Append(condition.attribute); var attrMeta = FetchXmlBuilder.GetAttribute(entityname, condition.attribute); if (attrMeta == null) { throw new Exception($"No metadata for attribute: {entityname}.{condition.attribute}"); } switch (condition.@operator) { case @operator.eq: case @operator.on: result.Append(" = "); break; case @operator.ne: case @operator.neq: result.Append(" != "); break; case @operator.lt: result.Append(" < "); break; case @operator.le: case @operator.onorbefore: result.Append(" <= "); break; case @operator.gt: result.Append(" > "); break; case @operator.ge: case @operator.onorafter: result.Append(" >= "); break; case @operator.@null: result.Append(" IS NULL"); break; case @operator.notnull: result.Append(" IS NOT NULL"); break; case @operator.like: result.Append(" LIKE "); break; case @operator.notlike: result.Append(" NOT LIKE "); break; //case @operator.beginswith: // result.Append(" LIKE \"{0}%\""); // break; //case @operator.@in: // result.Append(" IN "); // break; //case @operator.notin: // result.Append(" NOT IN "); // break; default: throw new Exception($"Unsupported SQL condition operator '{condition.@operator}'"); } if (!string.IsNullOrEmpty(condition.value)) { switch (attrMeta.AttributeType) { case AttributeTypeCode.Money: case AttributeTypeCode.BigInt: case AttributeTypeCode.Boolean: case AttributeTypeCode.Decimal: case AttributeTypeCode.Double: case AttributeTypeCode.Integer: case AttributeTypeCode.State: case AttributeTypeCode.Status: case AttributeTypeCode.Picklist: result.Append(condition.value); break; default: result.Append($"'{condition.value}'"); break; } } } return(result.ToString()); }
private static string GetSelect(FetchEntityType entity, FetchXmlBuilder sender) { var result = ""; var attributeitems = entity.Items.Where(i => i is FetchAttributeType && ((FetchAttributeType)i).name != null).ToList(); if (attributeitems.Count > 0) { foreach (FetchAttributeType attributeitem in attributeitems) { result += LogicalToSchemaName(entity.name, attributeitem.name, sender) + ","; } } return result; }
public filterControl(Dictionary <string, string> collection, FetchXmlBuilder fetchXmlBuilder, TreeBuilderControl tree) { InitializeComponent(); InitializeFXB(collection, fetchXmlBuilder, tree, null); }
private static string LogicalToSchemaName(string entity, FetchXmlBuilder sender) { GetEntityMetadata(entity, sender); var entityMeta = FetchXmlBuilder.entities[entity]; return entityMeta.SchemaName; }
private static string GetWhere(string entityname, string entityalias, List <object> filteritems, FetchXmlBuilder fxb) { var resultList = new StringBuilder(); if (filteritems.Count > 0) { foreach (filter filteritem in filteritems) { resultList.Append(GetFilter(entityname, entityalias, filteritem, fxb)); } } return(resultList.ToString()); }
private static string GetCondition(FetchEntityType entity, condition condition, FetchXmlBuilder sender) { var result = ""; if (!string.IsNullOrEmpty(condition.attribute)) { GetEntityMetadata(entity.name, sender); var attrMeta = FetchXmlBuilder.GetAttribute(entity.name, condition.attribute); if (attrMeta == null) { throw new Exception($"No metadata for attribute: {entity.name}.{condition.attribute}"); } result = attrMeta.SchemaName; switch (attrMeta.AttributeType) { case AttributeTypeCode.Picklist: case AttributeTypeCode.Money: case AttributeTypeCode.State: case AttributeTypeCode.Status: result += "/Value"; break; case AttributeTypeCode.Lookup: result += "/Id"; break; } switch (condition.@operator) { case @operator.eq: case @operator.ne: case @operator.lt: case @operator.le: case @operator.gt: case @operator.ge: result += $" {condition.@operator} "; break; case @operator.neq: result += " ne "; break; case @operator.@null: result += " eq null"; break; case @operator.notnull: result += " ne null"; break; case @operator.like: result = $"substringof('{condition.value}', {attrMeta.SchemaName})"; break; case @operator.notlike: result = $"not substringof('{condition.value}', {attrMeta.SchemaName})"; break; case @operator.@in: case @operator.notin: throw new Exception($"Condition operator '{condition.@operator}' is not yet supported by the OData generator"); default: throw new Exception($"Unsupported OData condition operator '{condition.@operator}'"); } if (!string.IsNullOrEmpty(condition.value) && condition.@operator != @operator.like && condition.@operator != @operator.notlike) { switch (attrMeta.AttributeType) { case AttributeTypeCode.Money: case AttributeTypeCode.BigInt: case AttributeTypeCode.Boolean: case AttributeTypeCode.Decimal: case AttributeTypeCode.Double: case AttributeTypeCode.Integer: case AttributeTypeCode.State: case AttributeTypeCode.Status: case AttributeTypeCode.Picklist: result += condition.value; break; case AttributeTypeCode.Uniqueidentifier: case AttributeTypeCode.Lookup: case AttributeTypeCode.Customer: case AttributeTypeCode.Owner: result += $"(guid'{condition.value}')"; break; case AttributeTypeCode.DateTime: result += $"datetime'{condition.value}'"; break; default: result += $"'{condition.value}'"; break; } } } return result; }
private void LinkHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { FetchXmlBuilder.OpenURL("https://docs.microsoft.com/en-us/connectors/commondataservice/#list-records"); }
public SelectViewDialog(FetchXmlBuilder caller) { InitializeComponent(); Caller = caller; PopulateForm(); }
public static void SetNodeText(TreeNode node, bool friendly) { if (node == null) { return; } var text = node.Name; Dictionary <string, string> attributes = node.Tag is Dictionary <string, string>? (Dictionary <string, string>)node.Tag: new Dictionary <string, string>(); var agg = GetAttributeFromNode(node, "aggregate"); var name = GetAttributeFromNode(node, "name"); var alias = GetAttributeFromNode(node, "alias"); switch (node.Name) { case "fetch": if (attributes.ContainsKey("top")) { text += " top:" + attributes["top"]; } if (attributes.ContainsKey("count")) { text += " cnt:" + attributes["count"]; } if (attributes.ContainsKey("returntotalrecordcount") && attributes["returntotalrecordcount"] == "true") { text += " reccnt"; } if (attributes.ContainsKey("aggregate") && attributes["aggregate"] == "true") { text += " aggr"; } if (attributes.ContainsKey("distinct") && attributes["distinct"] == "true") { text += " dist"; } if (attributes.ContainsKey("page")) { text += " pg:" + attributes["page"]; } break; case "entity": case "link-entity": text += " " + FetchXmlBuilder.GetEntityDisplayName(name); if (!string.IsNullOrEmpty(alias)) { text += " (" + alias + ")"; } if (GetAttributeFromNode(node, "intersect") == "true") { text += " M:M"; } break; case "attribute": if (!string.IsNullOrEmpty(name)) { text += " "; if (node.Parent != null) { var parent = GetAttributeFromNode(node.Parent, "name"); name = FetchXmlBuilder.GetAttributeDisplayName(parent, name); } if (!string.IsNullOrEmpty(agg) && !string.IsNullOrEmpty(name)) { if (!string.IsNullOrEmpty(alias)) { text += alias + "="; } text += agg + "(" + name + ")"; } else if (!string.IsNullOrEmpty(alias)) { text += alias + " (" + name + ")"; } else { text += name; } var grp = GetAttributeFromNode(node, "groupby"); if (grp == "true") { text += " GRP"; } } break; case "filter": var type = GetAttributeFromNode(node, "type"); if (!string.IsNullOrEmpty(type)) { text += " (" + type + ")"; } break; case "condition": { var ent = GetAttributeFromNode(node, "entityname"); var attr = GetAttributeFromNode(node, "attribute"); var oper = GetAttributeFromNode(node, "operator"); var val = GetAttributeFromNode(node, "value"); if (node.Parent != null && node.Parent.Parent != null) { var parent = GetAttributeFromNode(node.Parent.Parent, "name"); attr = FetchXmlBuilder.GetAttributeDisplayName(parent, attr); } if (!string.IsNullOrEmpty(ent)) { attr = ent + "." + attr; } if (oper.Contains("-x-")) { oper = oper.Replace("-x-", " " + val + " "); val = ""; } text += (" " + attr + " " + oper + " " + val).TrimEnd(); } break; case "value": var value = GetAttributeFromNode(node, "#text"); text += " " + value; break; case "order": { var attr = GetAttributeFromNode(node, "attribute"); var desc = GetAttributeFromNode(node, "descending"); if (!string.IsNullOrEmpty(alias)) { text += " " + alias; } else if (!string.IsNullOrEmpty(attr)) { if (!string.IsNullOrEmpty(attr) && node.Parent != null) { var parent = GetAttributeFromNode(node.Parent, "name"); attr = FetchXmlBuilder.GetAttributeDisplayName(parent, attr); } { text += " " + attr; } } if (desc == "true") { text += " Desc"; } } break; case "#comment": text = GetAttributeFromNode(node, "#comment").Trim().Replace("\r\n", " "); if (string.IsNullOrWhiteSpace(text)) { text = " - comment - "; } break; } if (friendly && !string.IsNullOrEmpty(text)) { text = text.Substring(0, 1).ToUpper() + text.Substring(1); } node.Text = text; SetNodeTooltip(node); }
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { FetchXmlBuilder.OpenURL(webRelease.Source.ToString()); Close(); }
public FlowListControl(FetchXmlBuilder fetchXmlBuilder) { fxb = fetchXmlBuilder; InitializeComponent(); TabText = Text; }
private static string GetExpand(FetchEntityType entity, FetchXmlBuilder sender, ref string select) { var result = ""; var linkitems = entity.Items.Where(i => i is FetchLinkEntityType).ToList(); if (linkitems.Count > 0) { foreach (FetchLinkEntityType linkitem in linkitems) { if (linkitem.linktype== "outer") { throw new Exception("OData queries do not support outer joins"); } if (linkitem.Items != null) { if (!linkitem.intersect && linkitem.Items.Where(i => i is FetchLinkEntityType).ToList().Count > 0) { throw new Exception("OData queries only support one level of link entities"); } if (linkitem.Items.Where(i => i is filter).ToList().Count > 0) { throw new Exception("OData queries do not support filter on link entities"); } if (linkitem.Items.Where(i => i is FetchOrderType).ToList().Count > 0) { throw new Exception("OData queries do not support sorting on link entities"); } } var relation = LinkItemToRelation(entity.name, linkitem, sender); result += relation.SchemaName + ","; select += GetExpandedSelect(linkitem, relation.SchemaName, sender); } } return result; }
public Settings(FetchXmlBuilder fxb) { InitializeComponent(); this.fxb = fxb; PopulateSettings(fxb.settings); }
private static string GetExpandedSelect(FetchLinkEntityType linkitem, string relation, FetchXmlBuilder sender) { if (linkitem.Items == null) { return ""; } var result = ""; var linkentity = linkitem.name; var attributeitems = linkitem.Items.Where(i => i is FetchAttributeType && ((FetchAttributeType)i).name != null).ToList(); if (linkitem.intersect) { var linkitems = linkitem.Items.Where(i => i is FetchLinkEntityType).ToList(); if (linkitems.Count > 1) { throw new Exception("Invalid M:M-relation definition for OData"); } if (linkitems.Count == 1) { var nextlink = (FetchLinkEntityType)linkitems[0]; linkentity = nextlink.name; attributeitems = nextlink.Items.Where(i => i is FetchAttributeType && ((FetchAttributeType)i).name != null).ToList(); } } if (attributeitems.Count > 0) { foreach (FetchAttributeType attributeitem in attributeitems) { result += relation + "/" + LogicalToSchemaName(linkentity, attributeitem.name, sender) + ","; } } return result; }
private void helpIcon_Click(object sender, System.EventArgs e) { FetchXmlBuilder.HelpClick(sender); }
private static List <string> GetJoin(List <object> linkentities, string entityalias, FetchXmlBuilder fxb) { var joinList = new List <string>(); foreach (FetchLinkEntityType linkitem in linkentities) { var join = new StringBuilder(); if (linkitem.linktype == "outer") { join.Append("LEFT OUTER "); } var linkalias = string.IsNullOrEmpty(linkitem.alias) ? linkitem.name : linkitem.alias; if (linkalias != linkitem.name) { aliasmap.Add(linkalias, linkitem.name); } join.Append($"JOIN {linkitem.name} {linkalias} ON {linkalias}.{linkitem.from} = {entityalias}.{linkitem.to}"); if (linkitem.Items != null) { var linkwhere = GetWhere(linkitem.name, linkalias, linkitem.Items.Where(i => i is filter && ((filter)i).Items != null && ((filter)i).Items.Length > 0).ToList(), fxb); if (!string.IsNullOrEmpty(linkwhere)) { join.Append($" AND {linkwhere} "); } } joinList.Add(join.ToString().Trim()); if (linkitem.Items != null) { selectcols.AddRange(GetExpandedSelect(linkitem, linkalias)); ordercols.AddRange(GetOrder(linkitem.Items.Where(i => i is FetchOrderType).ToList(), linkalias)); joinList.AddRange(GetJoin(linkitem.Items.Where(i => i is FetchLinkEntityType).ToList(), linkalias, fxb)); } } return(joinList); }
private static void GetEntityMetadata(string entity, FetchXmlBuilder sender) { if (sender.NeedToLoadEntity(entity)) { sender.LoadEntityDetails(entity, null, false); } if (!FetchXmlBuilder.entities.ContainsKey(entity)) { throw new Exception($"No metadata for entity: {entity}"); } }
/// <summary> /// Adds a new TreeNode to the parent object from the XmlNode information /// </summary> /// <param name="parentObject">Object (TreeNode or TreeView) where to add a new TreeNode</param> /// <param name="xmlNode">Xml node from the sitemap</param> /// <param name="tree">Current application form</param> /// <param name="isDisabled"> </param> public static TreeNode AddTreeViewNode(object parentObject, XmlNode xmlNode, TreeBuilderControl tree, FetchXmlBuilder fxb, int index = -1) { TreeNode node = null; if (xmlNode is XmlElement || xmlNode is XmlComment) { node = new TreeNode(xmlNode.Name); node.Name = xmlNode.Name; Dictionary <string, string> attributes = new Dictionary <string, string>(); if (xmlNode.NodeType == XmlNodeType.Comment) { attributes.Add("#comment", xmlNode.Value); node.ForeColor = System.Drawing.Color.Gray; } else if (xmlNode.Attributes != null) { foreach (XmlAttribute attr in xmlNode.Attributes) { attributes.Add(attr.Name, attr.Value); } } if (parentObject is TreeView) { ((TreeView)parentObject).Nodes.Add(node); } else if (parentObject is TreeNode) { if (index == -1) { ((TreeNode)parentObject).Nodes.Add(node); } else { ((TreeNode)parentObject).Nodes.Insert(index, node); } } else { throw new Exception("AddTreeViewNode: Unsupported control type"); } node.Tag = attributes; AddContextMenu(node, tree); foreach (XmlNode childNode in xmlNode.ChildNodes) { AddTreeViewNode(node, childNode, tree, fxb); } SetNodeText(node, fxb); } else if (xmlNode is XmlText && parentObject is TreeNode) { var treeNode = (TreeNode)parentObject; if (treeNode.Tag is Dictionary <string, string> ) { var attributes = (Dictionary <string, string>)treeNode.Tag; attributes.Add("#text", ((XmlText)xmlNode).Value); } } return(node); }