void WireUpEvents(string ribbonTypes, string dynamicContext, XContainer ribbonDoc, XNamespace xNamespace) { //Go through each type of Ribbon foreach (string ribbonControl in controlCallbackLookup.RibbonControls) { //Get each instance of that control in the ribbon definition file IEnumerable <XElement> xElements = ribbonDoc.Descendants(XName.Get(ribbonControl, xNamespace.NamespaceName)); foreach (XElement xElement in xElements) { XAttribute elementId = xElement.Attribute(XName.Get("id")); XAttribute elementQId = xElement.Attribute(XName.Get("idQ")); //Go through each possible callback, Concat with common methods on all controls foreach (string controlCallback in controlCallbackLookup.GetVstoControlCallbacks(ribbonControl)) { //Look for a defined callback XAttribute callbackAttribute = xElement.Attribute(XName.Get(controlCallback)); if (callbackAttribute == null) { continue; } if (elementId == null && elementQId == null) { throw new InvalidOperationException(string.Format( "VSTO Contrib Requires controls to have an id or an idQ when callbacks are registered. Control='{0}', Callback='{1}'", ribbonControl, controlCallback)); } string currentCallback = callbackAttribute.Value; //Set the callback value to the callback method defined on this factory string factoryMethodName = controlCallbackLookup.GetFactoryMethodName(ribbonControl, controlCallback); callbackAttribute.SetValue(factoryMethodName); //Set the tag attribute of the element, this is needed to know where to // direct the callback var id = (elementId ?? elementQId).Value; string callbackTag = BuildTag(ribbonTypes, id, factoryMethodName); vstoContribContext.TagToCallbackTargetLookup.Add(callbackTag, new CallbackTarget(ribbonTypes, dynamicContext, currentCallback)); xElement.SetAttributeValue(XName.Get("tag"), (ribbonTypes + id)); ribbonViewModelResolver.RegisterCallbackControl(ribbonTypes, currentCallback, id); } } } }