diff --git a/src/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows/UWPtoWinAppSDKUpgrade/WinUIContentDialogCodeFixer.cs b/src/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows/UWPtoWinAppSDKUpgrade/WinUIContentDialogCodeFixer.cs index 313cb1b2..3f281312 100644 --- a/src/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows/UWPtoWinAppSDKUpgrade/WinUIContentDialogCodeFixer.cs +++ b/src/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows/UWPtoWinAppSDKUpgrade/WinUIContentDialogCodeFixer.cs @@ -21,6 +21,8 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Windows [ApplicableComponents(ProjectComponents.WinUI)] public class WinUIContentDialogCodeFixer : CodeFixProvider { + private const string DialogSetterComment = "/* TODO You should replace 'this' with the instance of UserControl that is ContentDialog is meant to be a part of. */"; + // The Upgrade Assistant will only use analyzers that have an associated code fix provider registered including // the analyzer's ID in the code fix provider's FixableDiagnosticIds array. public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(WinUIContentDialogAnalyzer.DiagnosticId); @@ -63,24 +65,27 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Windows { var newMethodDeclarationSibling = contentDialogMemberAccess.Ancestors().OfType().First(); - var newMethodAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("this"), - SyntaxFactory.IdentifierName("SetContentDialogRoot")); - var newMethodCall = SyntaxFactory.InvocationExpression(newMethodAccess, - SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(contentDialogMemberAccess.Expression) }))); + var newMethodCall = SyntaxFactory.InvocationExpression(SyntaxFactory.ParseExpression("SetContentDialogRoot"), + SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] + { + SyntaxFactory.Argument(contentDialogMemberAccess.Expression), + SyntaxFactory.Argument(SyntaxFactory.ParseExpression("this")) + }))); + var newMethodCallComment = SyntaxFactory.Comment(DialogSetterComment); var documentEditor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); - documentEditor.ReplaceNode(contentDialogMemberAccess.Expression, newMethodCall); + documentEditor.ReplaceNode(contentDialogMemberAccess.Expression, newMethodCall.WithLeadingTrivia(newMethodCallComment)); if (!newMethodDeclarationSibling.Parent!.ChildNodes().OfType() .Any(sibling => sibling.Identifier.ValueText == "SetContentDialogRoot")) { var newMethodRoot = await CSharpSyntaxTree.ParseText(@" class A { - private ContentDialog SetContentDialogRoot(ContentDialog contentDialog) + private static ContentDialog SetContentDialogRoot(ContentDialog contentDialog, UserControl control) { if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent(""Windows.Foundation.UniversalApiContract"", 8)) { - contentDialog.XamlRoot = this.Content.XamlRoot; + contentDialog.XamlRoot = control.Content.XamlRoot; } return contentDialog; } diff --git a/src/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows/UWPtoWinAppSDKUpgrade/WinUIInitializeWindowCodeFixer.cs b/src/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows/UWPtoWinAppSDKUpgrade/WinUIInitializeWindowCodeFixer.cs index 37689f54..5af34dcf 100644 --- a/src/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows/UWPtoWinAppSDKUpgrade/WinUIInitializeWindowCodeFixer.cs +++ b/src/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows/UWPtoWinAppSDKUpgrade/WinUIInitializeWindowCodeFixer.cs @@ -20,6 +20,10 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Windows [ApplicableComponents(ProjectComponents.WinUI)] public class WinUIInitializeWindowCodeFixer : CodeFixProvider { + private const string WindowInitializerComment = @"/* TODO You should replace 'App.WindowHandle' with the your window's handle (HWND) + Read more on retrieving window handle here: https://docs.microsoft.com/en-us/windows/apps/develop/ui-input/retrieve-hwnd */ + "; + // The Upgrade Assistant will only use analyzers that have an associated code fix provider registered including // the analyzer's ID in the code fix provider's FixableDiagnosticIds array. public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(DiagnosticId); @@ -66,12 +70,16 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Windows var newMethodDeclarationSibling = objectCreationDeclaration.Ancestors().OfType().First(); var typeName = objectCreationDeclaration.Type.ToString(); - var newMethodAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("this"), - SyntaxFactory.IdentifierName("InitializeWithWindow")); - var newMethodCall = SyntaxFactory.InvocationExpression(newMethodAccess, - SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(objectCreationDeclaration) }))); + var newMethodCall = SyntaxFactory.InvocationExpression(SyntaxFactory.ParseExpression("InitializeWithWindow"), + SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] + { + SyntaxFactory.Argument(objectCreationDeclaration), + SyntaxFactory.Argument(SyntaxFactory.ParseExpression("App.WindowHandle")) + }))); + + var newMethodCallComment = SyntaxFactory.Comment(WindowInitializerComment); + documentEditor.ReplaceNode(objectCreationDeclaration, newMethodCall.WithLeadingTrivia(newMethodCallComment)); - documentEditor.ReplaceNode(objectCreationDeclaration, newMethodCall); if (!newMethodDeclarationSibling.Parent!.ChildNodes().OfType() .Any(sibling => sibling.Identifier.ValueText == "InitializeWithWindow" && sibling.ParameterList.Parameters.Any(parameter => parameter.Type!.ToString() == typeName))) @@ -79,9 +87,9 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Windows var newMethodRoot = await CSharpSyntaxTree.ParseText(@$" class A {{ - private {typeName} InitializeWithWindow({typeName} obj) + private static {typeName} InitializeWithWindow({typeName} obj, IntPtr windowHandle) {{ - WinRT.Interop.InitializeWithWindow.Initialize(obj, App.WindowHandle); + WinRT.Interop.InitializeWithWindow.Initialize(obj, windowHandle); return obj; }} }}", diff --git a/tests/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows.Tests/assets/TestClasses/ContentDialogCaller.Fixed.cs b/tests/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows.Tests/assets/TestClasses/ContentDialogCaller.Fixed.cs index 6603ac12..c57816e8 100644 --- a/tests/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows.Tests/assets/TestClasses/ContentDialogCaller.Fixed.cs +++ b/tests/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows.Tests/assets/TestClasses/ContentDialogCaller.Fixed.cs @@ -20,13 +20,13 @@ namespace TestProject.TestClasses PrimaryButtonText = "Leave this page", SecondaryButtonText = "Stay" }; - ContentDialogResult result = this.SetContentDialogRoot(saveDialog).ShowAsync(); + ContentDialogResult result = /* TODO You should replace 'this' with the instance of UserControl that is ContentDialog is meant to be a part of. */SetContentDialogRoot(saveDialog, this).ShowAsync(); } - private ContentDialog SetContentDialogRoot(ContentDialog contentDialog) + private static ContentDialog SetContentDialogRoot(ContentDialog contentDialog, UserControl control) { if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8)) { - contentDialog.XamlRoot = this.Content.XamlRoot; + contentDialog.XamlRoot = control.Content.XamlRoot; } return contentDialog; } diff --git a/tests/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows.Tests/assets/TestClasses/InitializeWithWindow.Fixed.cs b/tests/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows.Tests/assets/TestClasses/InitializeWithWindow.Fixed.cs index 77fe46bd..0250c375 100644 --- a/tests/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows.Tests/assets/TestClasses/InitializeWithWindow.Fixed.cs +++ b/tests/extensions/windows/Microsoft.DotNet.UpgradeAssistant.Extensions.Windows.Tests/assets/TestClasses/InitializeWithWindow.Fixed.cs @@ -14,18 +14,22 @@ namespace TestProject.TestClasses { private async void CallContentDialog() { - var filePicker = this.InitializeWithWindow(new FileSavePicker()); - var folderPicker = this.InitializeWithWindow(new FolderPicker()); + var filePicker = /* TODO You should replace 'App.WindowHandle' with the your window's handle (HWND) + Read more on retrieving window handle here: https://docs.microsoft.com/en-us/windows/apps/develop/ui-input/retrieve-hwnd */ + InitializeWithWindow(new FileSavePicker(), App.WindowHandle); + var folderPicker = /* TODO You should replace 'App.WindowHandle' with the your window's handle (HWND) + Read more on retrieving window handle here: https://docs.microsoft.com/en-us/windows/apps/develop/ui-input/retrieve-hwnd */ + InitializeWithWindow(new FolderPicker(), App.WindowHandle); var fileOpenPicker = this.InitializeWithWindow(new FileOpenPicker()); } - private FolderPicker InitializeWithWindow(FolderPicker obj) + private static FolderPicker InitializeWithWindow(FolderPicker obj, IntPtr windowHandle) { - WinRT.Interop.InitializeWithWindow.Initialize(obj, App.WindowHandle); + WinRT.Interop.InitializeWithWindow.Initialize(obj, windowHandle); return obj; } - private FileSavePicker InitializeWithWindow(FileSavePicker obj) + private static FileSavePicker InitializeWithWindow(FileSavePicker obj, IntPtr windowHandle) { - WinRT.Interop.InitializeWithWindow.Initialize(obj, App.WindowHandle); + WinRT.Interop.InitializeWithWindow.Initialize(obj, windowHandle); return obj; }