dotnet/wpf · error · NotSupportedException
SR.ToolBar_InvalidStyle_ToolBarPanel
Error message
SR.ToolBar_InvalidStyle_ToolBarPanel
What it means
ToolBar.FindToolBarPanel looks up the template child named ToolBarPanelTemplateName and requires it to be a ToolBarPanel. If the template contains an element with that name that is not a ToolBarPanel, it throws NotSupportedException (SR.ToolBar_InvalidStyle_ToolBarPanel) naming the actual type. The library throws because ToolBar layout depends on ToolBarPanel's special overflow logic.
Solutions
- In the custom ToolBar template, make the element named PART_ToolBarPanel an actual ToolBarPanel.
- Remove the PART_ToolBarPanel-named child entirely if you do not want the default behavior, rather than giving it the wrong type.
- Compare against the default Aero/Fluent ToolBar template and restore the correct part types.
Example fix
<!-- before --> <ControlTemplate TargetType="ToolBar"> <StackPanel x:Name="PART_ToolBarPanel" IsItemsHost="True"/> </ControlTemplate> <!-- after --> <ControlTemplate TargetType="ToolBar"> <ToolBarPanel x:Name="PART_ToolBarPanel" IsItemsHost="True"/> </ControlTemplate>
Defensive patterns
Strategy: validation
Validate before calling
// In template authoring/CI: assert required part types
var panel = template.FindName("PART_ToolBarPanel", toolBar) as ToolBarPanel;
if (panel == null) throw new InvalidOperationException("Template must declare PART_ToolBarPanel as ToolBarPanel"); Type guard
bool ok = VisualTreeHelper.GetChild(toolBar, i) is ToolBarPanel;
Try / catch
try
{
toolBar.ApplyTemplate();
}
catch (NotSupportedException ex)
{
// log template part type error; revert to default ToolBar style
} Prevention
- Respect WPF template-part contracts: PART_ToolBarPanel must be ToolBarPanel.
- Start custom templates from the default theme template and only restyle, don't retype, parts.
- Smoke-test custom control templates on app startup (force ApplyTemplate) in CI.
When it happens
Trigger: Applying a custom ControlTemplate for ToolBar (via Style/Template or theme change) that includes a child named "PART_ToolBarPanel" (ToolBarPanelTemplateName) whose type is not ToolBarPanel.
Common situations: Hand-written or copied custom ToolBar templates where PART_ToolBarPanel is a StackPanel/Grid/Canvas; renaming or retyping the part during restyling; migrating templates across WPF versions where template parts contract is not respected.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- SR.ToolBar_InvalidStyle_ToolBarOverflowPanel
- Animation_ChildMustBeKeyFrame
- Animation_ChildMustBeKeyFrame
- Animation_NoTextChildren
- Animation_NoTextChildren
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ed094b2881b663f4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ToolBar.cs:596
/// Gets reference to ToolBar's ToolBarPanel element.
/// </summary>
internal ToolBarPanel ToolBarPanel
{
get
{
if (_toolBarPanel == null)
_toolBarPanel = FindToolBarPanel();
return _toolBarPanel;
}
}
private ToolBarPanel FindToolBarPanel()
{
DependencyObject child = GetTemplateChild(ToolBarPanelTemplateName);
ToolBarPanel toolBarPanel = child as ToolBarPanel;
if (child != null && toolBarPanel == null)
throw new NotSupportedException(SR.Format(SR.ToolBar_InvalidStyle_ToolBarPanel, child.GetType()));
return toolBarPanel;
}
/// <summary>
/// Gets reference to ToolBar's ToolBarOverflowPanel element.
/// </summary>
internal ToolBarOverflowPanel ToolBarOverflowPanel
{
get
{
if (_toolBarOverflowPanel == null)
_toolBarOverflowPanel = FindToolBarOverflowPanel();
return _toolBarOverflowPanel;
}
}
private ToolBarOverflowPanel FindToolBarOverflowPanel()View on GitHub (pinned to 81131a70a4)