MaterialDesignInXAML/MaterialDesignInXamlToolkit · error · ArgumentException
visualAncestry must contains at least one Visual control ins
Error message
visualAncestry must contains at least one Visual control inside.
What it means
Inside `ComboBoxPopup.GetPositioningData` (a local function used during custom popup placement), `mainVisual = visualAncestry.OfType<Visual>().LastOrDefault()` is expected to be the root presentation source. If the `PlacementTarget`'s visual ancestry contains no `Visual`, it throws `ArgumentException`, because DPI/transform calculations need a real visual root.
Source
Thrown at src/MaterialDesignThemes.Wpf/ComboBoxPopup.cs:250
{
newY = -(defaultVerticalOffsetIndependent + data.PopupSize.Height);
direction = PopupDirection.Up;
}
else
{
newY = defaultVerticalOffsetIndependent + data.TargetSize.Height;
direction = PopupDirection.Down;
}
SetCurrentValue(OpenDirectionProperty, direction);
return new[] { new CustomPopupPlacement(new Point(data.OffsetX, newY), PopupPrimaryAxis.Horizontal) };
PositioningData GetPositioningData(IEnumerable<DependencyObject?> visualAncestry, Size popupSize, Size targetSize)
{
var locationFromScreen = PlacementTarget.PointToScreen(new Point(0, 0));
var mainVisual = visualAncestry.OfType<Visual>().LastOrDefault()
?? throw new ArgumentException($"{nameof(visualAncestry)} must contains at least one {nameof(Visual)} control inside.");
var controlVisual = visualAncestry.OfType<Visual>().FirstOrDefault()
?? throw new ArgumentException($"{nameof(visualAncestry)} must contains at least one {nameof(Visual)} control inside.");
var screen = Screen.FromPoint(locationFromScreen);
var screenWidth = (int)screen.Bounds.Width;
var screenHeight = (int)screen.Bounds.Height;
//Adjust the location to be in terms of the current screen
var locationX = (int)(locationFromScreen.X - screen.Bounds.X) % screenWidth;
var locationY = (int)(locationFromScreen.Y - screen.Bounds.Y) % screenHeight;
var upVerticalOffsetIndependent = DpiHelper.TransformToDeviceY(mainVisual, UpVerticalOffset) * ScaleHelper.GetTotalTransformScaleY(controlVisual);
var newUpY = upVerticalOffsetIndependent - popupSize.Height + targetSize.Height;
var newDownY = DpiHelper.TransformToDeviceY(mainVisual, DownVerticalOffset) * ScaleHelper.GetTotalTransformScaleY(controlVisual);
var offsetX = DpiHelper.TransformToDeviceX(mainVisual, RelativeHorizontalOffset) * ScaleHelper.GetTotalTransformScaleX(controlVisual);
offsetX = FlowDirection == FlowDirection.LeftToRight
? Round(offsetX)
: Math.Truncate(offsetX - targetSize.Width);
View on GitHub (pinned to 98edec3a0b)
Solutions
- Ensure the `ComboBox`/`PlacementTarget` is loaded into a visible window before opening the dropdown (subscribe to `Loaded`).
- Avoid opening the popup during `Unloaded`/`Closed` or while the element is being reparented.
- If reproducing in design mode or tests, supply a real presentation source or suppress placement.
- Upgrade MaterialDesignThemes — defensive placement handling has improved across versions.
Example fix
// before comboBox.IsDropDownOpen = true; // called before the control is in a live visual tree -> throws // after comboBox.Loaded += (s, e) => comboBox.IsDropDownOpen = true;
Defensive patterns
Strategy: validation
Validate before calling
void OpenWhenLoaded(ComboBox cb)
{
if (cb.IsLoaded && AdornerLayer.GetAdornerLayer(cb) is not null)
cb.IsDropDownOpen = true;
else
cb.Loaded += (s, _) => cb.IsDropDownOpen = true;
} Type guard
static bool HasVisualAncestry(UIElement e)
=> PresentationSource.FromVisual(e as Visual) is not null; Prevention
- Open combo dropdowns only after Loaded.
- Don't open popups during Unloaded/teardown.
- Keep MaterialDesignThemes up to date for hardened placement logic.
When it happens
Trigger: The combo box popup performs custom placement while `PlacementTarget` is detached from any window/presentation source (no `Visual` ancestor): opening the popup before the control is in a live visual tree, during teardown, or on a disconnected element.
Common situations: Opening a `ComboBox` whose popup uses this host before `Loaded`; hosting the combo in a `Popup`/`ContextMenu` not yet shown; element removed from the tree while a placement pass runs; design-time/hosted scenarios without a real visual root.
Related errors
- This element has no adorner layer.
- No loaded DialogHost instances.
- DialogHost is not open.
- Non primary hues provided.
- Entry {entry.Key} was not of type Color
AI-assisted analysis of MaterialDesignInXAML/MaterialDesignInXamlToolkit@98edec3a0b (2026-08-13).
Data as JSON: /api/errors/44aa65d09d9b15a7.
Report an issue: GitHub.