Fix ComboBox displaying incorrectly in ViewBox in UWP/WinUI 2

The ComboBox is a commonly used control that can be used for selecting items from a drop down list. Unfortunately, there is a bug in UWP that causes UWP and WinUI 2 ComboBoxes not to display correctly when opened if the ComboBox is inside a ViewBox. The ComboBox's drop down  menu might appear too large or too small and it might appear blurry and/or cut off as well. Here is an example of what it might look like:



As you can see in the above screenshot, the ComboBox's drop down menu appears too large, blurred and cut off.

What causes this?

This issue is caused by a new feature introduced in Windows 10 1903 called ShouldConstrainToRootBounds. ShouldConstrainToRootBounds is a property that determines if a popup should show within its XAML root, or in a separate top level window. By showing the popup in a top level window, rather than in its XAML root, the popup is able to go beyond the bounds of its XAML root. Practically, for a standard UWP app, this means that a popup can display beyond the bounds of the app's window - so even if the app's window is too small or the popup to display for example, it can still display full size and in the correct position so long as it's not cut off by the edge of the screen. This is the same when used in an XAML island, except that it applies to the XAML island rather than the top-level window. You can investigate this behaviour further with our app Window Commander. Setting ShouldConstrainToRootBounds to false (allowing the popup to open in its own top-level window) can be very useful but unfortunately causes this issue - and ShouldConstrainToRootBounds is set to false by default on Windows Desktop! This issue has been reported here: ComboBox items not scaled properly when inside a Viewbox · Issue #1187 · microsoft/microsoft-ui-xaml (github.com).

How to fix this

The simple an obvious answer after reading the above information about what causes this would be to set ShouldConstrainToRootBounds to true, preventing the popup from showing in its own top-level window, preventing this issue from occurring in the first place. Unfortunately, the ComboBox does not expose this property. Luckily, one easy way to force ShouldConstrainToRootBounds to be set to true is to enable a rotation transform on the ComboBox like so:

<ComboBox>

    <ComboBox.RenderTransform>

        <CompositeTransform Rotation="0.01"/>

    </ComboBox.RenderTransform>

</ComboBox>


This will result in ShouldConstrainToRootBounds being set to true on Windows Desktop, causing the ComboBox to display correctly when opened:


If you don't want to set the transform in XAML, you can also do it in code, here are examples in C# and VB:

C#:

ComboBox.RenderTransformOrigin = new Point(0.5, 0.5);

ComboBox.RenderTransform = new CompositeTransform() { Rotation = 0.01 };


VB:

ComboBox.RenderTransformOrigin = New Point(0.5, 0.5)

ComboBox.RenderTransform = New CompositeTransform() With {.Rotation = 0.01}



Did this article help you? Do you know of a better way to achieve this? Let us know in the comments! Also, if you want to discuss and give your feedback on this issue to Microsoft, see the reported issue here: ComboBox items not scaled properly when inside a Viewbox · Issue #1187 · microsoft/microsoft-ui-xaml (github.com).


This snippet is available in Codly. Click the appropriate link below to download the snippet. If you don't have Codly, it is available here in the Microsoft Store.

Comments

Popular posts from this blog

How to enable dark title bar in Windows Forms and WPF (Windows Presentation Foundation) apps

How to show placeholder text in a WPF textbox

How to enable precision scrolling in a WPF app on Windows