Skip to content

[Problem/Bug]: Command binding in WinUI 3 is failing with native AOT enabled #5230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
aries-zhang opened this issue May 6, 2025 · 0 comments
Assignees
Labels
bug Something isn't working

Comments

@aries-zhang
Copy link

aries-zhang commented May 6, 2025

What happened?

Hi, I have an WinUI 3 app recently enabled native AOT but found that command binding stopped working only in the WebView2 control. Consider the following code:

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="WinAppWithNaot.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WinAppWithNaot"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    Title="WinAppWithNaot">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button x:Name="myButton" Command="{x:Bind ViewModel.ButtonCommand}">Click Me</Button>
        <WebView2 Name="webView2" Source="https://bing.com" Width="500" Height="500">
        <!--CoreWebView2Initialized="webView2_CoreWebView2Initialized" WebMessageReceived="webView2_WebMessageReceived"-->
            <i:Interaction.Behaviors>
                <i:EventTriggerBehavior EventName="CoreWebView2Initialized">
                    <i:InvokeCommandAction Command="{x:Bind ViewModel.InitializeCommand}"/>
                </i:EventTriggerBehavior>
            </i:Interaction.Behaviors>
        </WebView2> 
    </StackPanel>
</Window>
public class MainWindowViewModel 
{
    public ICommand ButtonCommand => new RelayCommand<RoutedEventArgs>(OnButtonClicked);

    public ICommand InitializeCommand => new RelayCommand<CoreWebView2InitializedEventArgs>(OnInitialized);

    private void OnInitialized(CoreWebView2InitializedEventArgs? args)
    {
        MessageBox(0, $"WebView2 Initialized", "", 0);
    }

    private void OnButtonClicked(RoutedEventArgs? e)
    {
        MessageBox(0, $"Button Clicked", "", 0);
    }

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern int MessageBox(nint hWnd, string text, string caption, int options);
}

// Here's the RelayCommand
public class RelayCommand<T> : ICommand
{
    private readonly Action<T?> ExecuteFunc;

    private readonly Predicate<T?>? CanExecuteFunc;

    public event EventHandler? CanExecuteChanged;

    public RelayCommand(Action<T?> execute)
    {
        ArgumentNullException.ThrowIfNull(execute);
        ExecuteFunc = execute;
    }

    public RelayCommand(Action<T?> execute, Predicate<T?> canExecute)
    {
        ExecuteFunc = execute;
        CanExecuteFunc = canExecute;
    }

    public bool CanExecute(object? parameter)
    {
        T? param = (T?)Convert.ChangeType(parameter, typeof(T), CultureInfo.InvariantCulture);

        return CanExecuteFunc is null || CanExecuteFunc(param);
    }

    public void Execute(object? parameter)
    {
        MainWindowViewModel.MessageBox(0, $"Execute called", "", 0);
        T? param = (T?)Convert.ChangeType(parameter, typeof(T), CultureInfo.InvariantCulture);

        ExecuteFunc(param);
    }
}

There is a button and a WebView2 control in the above app. When directly running the code from VisualStudio, the app behaves as expected: a message box shows when Webview2 initializes and another one when button is clicked. However, when the app is published, only the command bound with the button works. Nothing happens when WebView2 initializes. Also tried a few other events such as WebView2.WebMessageReceived/NavigationCompleted, but it looks like none works after app is published. Other WinUI 3 controls seem to work as expected (Tried Button.Click, StackPanel.Load in the above XAML).

Does anyone know if anything in WebView2 SDK is trimmed off? or is there any known incompatibility with WebView2 + Microsoft.Xaml.Interactivity?

Importance

Moderate. My app's user experience is affected, but still usable.

Runtime Channel

Stable release (WebView2 Runtime)

Runtime Version

No response

SDK Version

No response

Framework

WinUI3/WinAppSDK

Operating System

Windows 11

OS Version

No response

Repro steps

  1. Create an empty WinUI 3 app with Visual Studio.
  2. Check "Publish native AOT", or ensure there is <PublishAot>true</PublishAot> in the app's csproj.
  3. Copy the above XAML content into the MainWindow.xaml (but please note to change the class name).
  4. Copy MainWindowViewModel and RelayCommand classes into MainWindow.xaml.cs.
  5. Run the app, you should see a message box pops up when WebView2 loads, and another one shows when the button is clicked.
  6. Publish a sideload package of the app and install it.
  7. When the published app runs, there is no message box when WebView2 loads, but when the button is clicked, message box shows as expected.

Repros in Edge Browser

No, issue does not reproduce in the corresponding Edge version

Regression

No, this never worked

Last working version (if regression)

No response

@aries-zhang aries-zhang added the bug Something isn't working label May 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants