I've run into a curious problem trying to work with the AppTitleBar in a WinUI 3 program. The title bar is meant to reformat itself dynamically (for visually challenged users) which means I need to know where everything in the WindowChrome is. I'm using the system buttons in the top right of the window (held in the MinMaxCloseContainer, a Grid) as a reference for various characteristics so, once I find it in the visual tree, I save it's reference in a DependencyProperty.
The problem is, I'm getting a System.InvalidCastException: 'Unable to cast object of type 'Microsoft.UI.Xaml.GridLength' to type 'System.Double'.' exception in the property setter.
I am using the CommunityToolkit.Mvvm v7.1.2, and the Microsoft.WindowsAppSDK 1.1.1 (WinUI 3). The project targets .NET 6.0. The ViewModel is derived from ObservableRecipient.
Here is the code that searches the visual tree:
var clientAreaPresenter = VisualTreeHelper.GetParent(shellPage) as ContentPresenter;
var layoutRoot = VisualTreeHelper.GetParent(clientAreaPresenter) as Grid; // this is the content of the WindowChrome (chrome and program content)
var titleBarMinMaxCloseContainer = VisualTreeHelper.GetChild(layoutRoot, 1) as Grid; // the system Min, Max and close buttons on the title bar
var minMaxCloseContainer = VisualTreeHelper.GetChild(titleBarMinMaxCloseContainer, 0) as Grid; // this container holds three Buttons: Min, Max, Close
ViewModel.MinMaxCloseContainer = minMaxCloseContainer; // remember where this is
(last line sets the DependencyProperty) and here is the property definition in the viewmodel:
/// <summary>
/// The system area containing the min, max and close buttons on the title bar
/// </summary>
public Grid MinMaxCloseContainer
{
get => _minMaxCloseContainer;
set => SetProperty(ref _minMaxCloseContainer, value);
}
The setter is where the error occurs but the Call Stack shows it's actually in the SetProperty() method. Although this looks like a reference assignment, I think the SetProperty method is actually taking a private copy. The error is probably due to undefined values (double.NaN) in various properties of the minMaxCloseContainer instance (for example, .Height and .Width during initialization). The .NET code I've found for
I've tried: 1) attaching a cast to GridLength (not valid in static classes); 2) checking for undefined values and changing them before assigning the Grid (no effect); 3) customizing the GridLengthConverter. The last item is odd because the published .NET code says the default converter does handle casts from GridLength to Double, even with double.NaN values. It may be that WinUI hasn't implemented a GridLengthConverter yet.
Anyway, everything I've tried hasn't worked and I'm not really sure why the error is happening in the first place. Any ideas would be greatly appreciated. Thanks.
It appears that today's update to Visual Studio 2022 Enterprise has fixed the issue. Everything is working as expected now. I'm not sure what changed, but I'm using the following version, for those who are experiencing a similar issue: