简体   繁体   中英

Saving a Grid to a DependencyProperty in WinUI 3: Working with the AppTitleBar in WinUI 3

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:

MicrosoftCorporationII.WinAppRuntime.Main.1.1_1001.524.1918.0_x64__8wekyb3d8bb

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM