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}
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.
Really appreciate for sharing this. It was very useful.
ReplyDeleteNo worries! Glad we could help!
Delete