From c31d9d801b2de45ff00852eace661c4860f24297 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Fri, 21 Aug 2020 13:54:50 -0700 Subject: [PATCH 1/2] make viewmodellocator opt-out --- src/Uno/Prism.Uno/PrismApplicationBase.cs | 4 +++- src/Uno/Prism.Uno/Services/Dialogs/DialogService.cs | 8 ++++---- src/Wpf/Prism.Wpf/Common/MvvmHelpers.cs | 10 +++++++++- src/Wpf/Prism.Wpf/Mvvm/ViewModelLocator.cs | 11 ++++++----- src/Wpf/Prism.Wpf/PrismApplicationBase.cs | 2 ++ src/Wpf/Prism.Wpf/PrismBootstrapperBase.cs | 4 +++- .../Regions/RegionNavigationContentLoader.cs | 1 + src/Wpf/Prism.Wpf/Services/Dialogs/DialogService.cs | 8 ++++---- 8 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/Uno/Prism.Uno/PrismApplicationBase.cs b/src/Uno/Prism.Uno/PrismApplicationBase.cs index 6f72926c59..83e0a4a3d8 100644 --- a/src/Uno/Prism.Uno/PrismApplicationBase.cs +++ b/src/Uno/Prism.Uno/PrismApplicationBase.cs @@ -1,4 +1,5 @@ -using Prism.Events; +using Prism.Common; +using Prism.Events; using Prism.Ioc; using Prism.Logging; using Prism.Modularity; @@ -88,6 +89,7 @@ public virtual void Initialize() var shell = CreateShell(); if (shell != null) { + MvvmHelpers.AutowireViewModel(shell); _containerExtension.Resolve().NavigationFailed += (s, e) => Console.WriteLine($"Region navigation failed {e.Error}"); InitializeShell(shell); diff --git a/src/Uno/Prism.Uno/Services/Dialogs/DialogService.cs b/src/Uno/Prism.Uno/Services/Dialogs/DialogService.cs index 8231b57f53..d9e7bee1db 100644 --- a/src/Uno/Prism.Uno/Services/Dialogs/DialogService.cs +++ b/src/Uno/Prism.Uno/Services/Dialogs/DialogService.cs @@ -49,14 +49,14 @@ IDialogWindow CreateDialogWindow(string name) void ConfigureDialogWindowContent(string dialogName, IDialogWindow window, IDialogParameters parameters) { var content = _containerProvider.Resolve(dialogName); - var dialogContent = content as FrameworkElement; - if (dialogContent == null) + if (!(content is FrameworkElement dialogContent)) { throw new NullReferenceException("A dialog's content must be a FrameworkElement"); } - var viewModel = dialogContent.DataContext as IDialogAware; - if (viewModel == null) + MvvmHelpers.AutowireViewModel(content); + + if (!(dialogContent.DataContext is IDialogAware viewModel)) { throw new NullReferenceException($"A dialog's ViewModel must implement the IDialogAware interface ({dialogContent.DataContext})"); } diff --git a/src/Wpf/Prism.Wpf/Common/MvvmHelpers.cs b/src/Wpf/Prism.Wpf/Common/MvvmHelpers.cs index 136c409bdc..2072d42472 100644 --- a/src/Wpf/Prism.Wpf/Common/MvvmHelpers.cs +++ b/src/Wpf/Prism.Wpf/Common/MvvmHelpers.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; - +using Prism.Mvvm; #if HAS_WINUI using Windows.UI.Xaml; #else @@ -15,6 +15,14 @@ namespace Prism.Common /// public static class MvvmHelpers { + internal static void AutowireViewModel(object viewOrViewModel) + { + if(viewOrViewModel is FrameworkElement view && ViewModelLocator.GetAutoWireViewModel(view) is null) + { + ViewModelLocator.SetAutoWireViewModel(view, true); + } + } + /// /// Perform an on a view and viewmodel. /// diff --git a/src/Wpf/Prism.Wpf/Mvvm/ViewModelLocator.cs b/src/Wpf/Prism.Wpf/Mvvm/ViewModelLocator.cs index e4182b90e5..b55568aa55 100644 --- a/src/Wpf/Prism.Wpf/Mvvm/ViewModelLocator.cs +++ b/src/Wpf/Prism.Wpf/Mvvm/ViewModelLocator.cs @@ -16,16 +16,16 @@ public static class ViewModelLocator /// /// The AutoWireViewModel attached property. /// - public static DependencyProperty AutoWireViewModelProperty = DependencyProperty.RegisterAttached("AutoWireViewModel", typeof(bool), typeof(ViewModelLocator), new PropertyMetadata(defaultValue: false, propertyChangedCallback: AutoWireViewModelChanged)); + public static DependencyProperty AutoWireViewModelProperty = DependencyProperty.RegisterAttached("AutoWireViewModel", typeof(bool?), typeof(ViewModelLocator), new PropertyMetadata(defaultValue: null, propertyChangedCallback: AutoWireViewModelChanged)); /// /// Gets the value for the attached property. /// /// The target element. /// The attached to the element. - public static bool GetAutoWireViewModel(DependencyObject obj) + public static bool? GetAutoWireViewModel(DependencyObject obj) { - return (bool)obj.GetValue(AutoWireViewModelProperty); + return (bool?)obj.GetValue(AutoWireViewModelProperty); } /// @@ -33,7 +33,7 @@ public static bool GetAutoWireViewModel(DependencyObject obj) /// /// The target element. /// The value to attach. - public static void SetAutoWireViewModel(DependencyObject obj, bool value) + public static void SetAutoWireViewModel(DependencyObject obj, bool? value) { obj.SetValue(AutoWireViewModelProperty, value); } @@ -44,7 +44,8 @@ private static void AutoWireViewModelChanged(DependencyObject d, DependencyPrope if (!DesignerProperties.GetIsInDesignMode(d)) #endif { - if ((bool)e.NewValue) + var value = (bool?)e.NewValue; + if (value.HasValue && value.Value) { ViewModelLocationProvider.AutoWireViewModelChanged(d, Bind); } diff --git a/src/Wpf/Prism.Wpf/PrismApplicationBase.cs b/src/Wpf/Prism.Wpf/PrismApplicationBase.cs index e4a94e30f5..065c03e2c5 100644 --- a/src/Wpf/Prism.Wpf/PrismApplicationBase.cs +++ b/src/Wpf/Prism.Wpf/PrismApplicationBase.cs @@ -1,5 +1,6 @@ using System; using System.Windows; +using Prism.Common; using Prism.Ioc; using Prism.Modularity; using Prism.Regions; @@ -75,6 +76,7 @@ protected virtual void Initialize() var shell = CreateShell(); if (shell != null) { + MvvmHelpers.AutowireViewModel(shell); RegionManager.SetRegionManager(shell, _containerExtension.Resolve()); RegionManager.UpdateRegions(); InitializeShell(shell); diff --git a/src/Wpf/Prism.Wpf/PrismBootstrapperBase.cs b/src/Wpf/Prism.Wpf/PrismBootstrapperBase.cs index 701e496912..1d966ae349 100644 --- a/src/Wpf/Prism.Wpf/PrismBootstrapperBase.cs +++ b/src/Wpf/Prism.Wpf/PrismBootstrapperBase.cs @@ -1,4 +1,5 @@ -using Prism.Ioc; +using Prism.Common; +using Prism.Ioc; using Prism.Modularity; using Prism.Regions; using System; @@ -72,6 +73,7 @@ protected virtual void Initialize() var shell = CreateShell(); if (shell != null) { + MvvmHelpers.AutowireViewModel(shell); RegionManager.SetRegionManager(shell, _containerExtension.Resolve()); RegionManager.UpdateRegions(); InitializeShell(shell); diff --git a/src/Wpf/Prism.Wpf/Regions/RegionNavigationContentLoader.cs b/src/Wpf/Prism.Wpf/Regions/RegionNavigationContentLoader.cs index fba3201190..57a79aadf8 100644 --- a/src/Wpf/Prism.Wpf/Regions/RegionNavigationContentLoader.cs +++ b/src/Wpf/Prism.Wpf/Regions/RegionNavigationContentLoader.cs @@ -102,6 +102,7 @@ protected virtual object CreateNewRegionItem(string candidateTargetContract) try { newRegionItem = _container.Resolve(candidateTargetContract); + MvvmHelpers.AutowireViewModel(newRegionItem); } catch (Exception e) { diff --git a/src/Wpf/Prism.Wpf/Services/Dialogs/DialogService.cs b/src/Wpf/Prism.Wpf/Services/Dialogs/DialogService.cs index 6ca3512880..7e64e4a9af 100644 --- a/src/Wpf/Prism.Wpf/Services/Dialogs/DialogService.cs +++ b/src/Wpf/Prism.Wpf/Services/Dialogs/DialogService.cs @@ -106,12 +106,12 @@ protected virtual IDialogWindow CreateDialogWindow(string name) protected virtual void ConfigureDialogWindowContent(string dialogName, IDialogWindow window, IDialogParameters parameters) { var content = _containerExtension.Resolve(dialogName); - var dialogContent = content as FrameworkElement; - if (dialogContent == null) + if (!(content is FrameworkElement dialogContent)) throw new NullReferenceException("A dialog's content must be a FrameworkElement"); - var viewModel = dialogContent.DataContext as IDialogAware; - if (viewModel == null) + MvvmHelpers.AutowireViewModel(dialogContent); + + if (!(dialogContent.DataContext is IDialogAware viewModel)) throw new NullReferenceException("A dialog's ViewModel must implement the IDialogAware interface"); ConfigureDialogWindowProperties(window, dialogContent, viewModel); From 30a5b5bf010432c8380957d8b195e16b64540d5b Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Fri, 21 Aug 2020 14:08:38 -0700 Subject: [PATCH 2/2] remove debug code --- src/Uno/Prism.Uno/PrismApplicationBase.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Uno/Prism.Uno/PrismApplicationBase.cs b/src/Uno/Prism.Uno/PrismApplicationBase.cs index 83e0a4a3d8..5cdc21b928 100644 --- a/src/Uno/Prism.Uno/PrismApplicationBase.cs +++ b/src/Uno/Prism.Uno/PrismApplicationBase.cs @@ -90,7 +90,6 @@ public virtual void Initialize() if (shell != null) { MvvmHelpers.AutowireViewModel(shell); - _containerExtension.Resolve().NavigationFailed += (s, e) => Console.WriteLine($"Region navigation failed {e.Error}"); InitializeShell(shell); void FinalizeInitialization()