{"record":{"id":"d6d7f9749b4e4d68","repo":"dotnet/wpf","slug":"microsoft-windows-controls-sr-ribbon","errorCode":null,"errorMessage":"Microsoft.Windows.Controls.SR.Ribbon_ContextualTabHeadersSourceInvalid","messagePattern":"Microsoft\\.Windows\\.Controls\\.SR\\.Ribbon_ContextualTabHeadersSourceInvalid","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/System.Windows.Controls.Ribbon/Microsoft/Windows/Controls/Ribbon/Ribbon.cs","lineNumber":752,"sourceCode":"        public override void OnApplyTemplate()\n        {\n            base.OnApplyTemplate();\n\n            _itemsPresenter = GetTemplateChild(\"ItemsPresenter\") as ItemsPresenter;\n            _itemsPresenterPopup = this.GetTemplateChild(ItemsPresenterPopupTemplateName) as Popup;\n\n            _tabHeaderItemsControl = this.GetTemplateChild(\"TabHeaderItemsControl\") as RibbonTabHeaderItemsControl;\n            if (_tabHeaderItemsControl != null && _tabHeaderItemsControl.ItemsSource == null)\n            {\n                _tabHeaderItemsControl.ItemsSource = _tabHeaderItemsSource;\n            }\n\n            _groupHeaderItemsControl = this.GetTemplateChild(Ribbon.ContextualTabGroupItemsControlTemplateName) as RibbonContextualTabGroupItemsControl;\n            if (_groupHeaderItemsControl != null && _groupHeaderItemsControl.ItemsSource == null)\n            {\n                if (ContextualTabGroupsSource != null && ContextualTabGroups.Count > 0)\n                {\n                    throw new InvalidOperationException(Microsoft.Windows.Controls.SR.Ribbon_ContextualTabHeadersSourceInvalid);\n                }\n                if (ContextualTabGroupsSource != null)\n                {\n                    ContextualTabGroupItemsControl.ItemsSource = ContextualTabGroupsSource;\n                }\n                else if (ContextualTabGroups != null)\n                {\n                    ContextualTabGroupItemsControl.ItemsSource = ContextualTabGroups;\n                }\n            }\n\n            this.RibbonTitlePanel = this.GetTemplateChild(Ribbon.TitlePanelTemplateName) as RibbonTitlePanel;\n            _qatTopHost = this.GetTemplateChild(Ribbon.QatHostTemplateName) as UIElement;\n            _titleHost = this.GetTemplateChild(Ribbon.TitleHostTemplateName) as UIElement;\n            _helpPaneHost = this.GetTemplateChild(Ribbon.HelpPaneTemplateName) as UIElement;\n\n            PropertyHelper.TransferProperty(this, ContextMenuProperty);   // Coerce to get a default ContextMenu if none has been specified.\n            PropertyHelper.TransferProperty(this, RibbonControlService.CanAddToQuickAccessToolBarDirectlyProperty);","sourceCodeStart":734,"sourceCodeEnd":770,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/System.Windows.Controls.Ribbon/Microsoft/Windows/Controls/Ribbon/Ribbon.cs#L734-L770","documentation":"During Ribbon template application (OnApplyTemplate path), if the RibbonContextualTabGroupItemsControl was found but has no ItemsSource, the Ribbon refuses a configuration where both ContextualTabGroupsSource is set AND the manual ContextualTabGroups collection already contains items — the two ways of supplying contextual tab groups are mutually exclusive. It throws InvalidOperationException (Ribbon_ContextualTabHeadersSourceInvalid).","triggerScenarios":"Setting ContextualTabGroupsSource (a binding to an external collection) while manually adding RibbonContextualTabGroup items to the ContextualTabGroups collection, then applying the template.","commonSituations":"Mixing XAML-declared contextual tab groups (<Ribbon.ContextualTabGroups>) with a ContextualTabGroupsSource binding, often after refactoring from declarative items to a source binding without clearing the collection.","solutions":["Remove manual items from ContextualTabGroups when using ContextualTabGroupsSource.","Or remove the ContextualTabGroupsSource binding and populate ContextualTabGroups directly.","Choose one population strategy (source binding OR direct items) per Ribbon instance."],"exampleFix":"// before\n<Ribbon ContextualTabGroupsSource=\"{Binding Tabs}\">\n  <Ribbon.ContextualTabGroups>\n    <RibbonContextualTabGroup Header=\"Tools\"/>\n  </Ribbon.ContextualTabGroups>\n</Ribbon>\n// after\n<Ribbon ContextualTabGroupsSource=\"{Binding Tabs}\"/>","handlingStrategy":"validation","validationCode":"bool ok = ribbon.ContextualTabGroupsSource == null || ribbon.ContextualTabGroups.Count == 0;\nif (!ok) throw new InvalidOperationException(\"Use either ContextualTabGroupsSource or ContextualTabGroups, not both.\");","typeGuard":null,"tryCatchPattern":"try { ApplyTemplate(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"ContextualTab\")) { ribbon.ContextualTabGroups.Clear(); ApplyTemplate(); }","preventionTips":["Pick one population strategy per Ribbon: source binding or direct items.","When adding ContextualTabGroupsSource, first clear ContextualTabGroups.","Review XAML for leftover <Ribbon.ContextualTabGroups> after introducing bindings."],"tags":["wpf","ribbon","invalidoperation","xaml"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}