/ src / modules / cmdpal / Microsoft.CmdPal.UI / ExtViews / ContentPage.xaml.cs
ContentPage.xaml.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  
  5  using CommunityToolkit.Mvvm.Messaging;
  6  using Microsoft.CmdPal.Core.ViewModels;
  7  using Microsoft.CmdPal.Core.ViewModels.Messages;
  8  using Microsoft.UI.Dispatching;
  9  using Microsoft.UI.Xaml;
 10  using Microsoft.UI.Xaml.Controls;
 11  using Microsoft.UI.Xaml.Navigation;
 12  
 13  namespace Microsoft.CmdPal.UI;
 14  
 15  /// <summary>
 16  /// An empty page that can be used on its own or navigated to within a Frame.
 17  /// </summary>
 18  public sealed partial class ContentPage : Page,
 19       IRecipient<ActivateSelectedListItemMessage>,
 20       IRecipient<ActivateSecondaryCommandMessage>
 21  {
 22      private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread();
 23  
 24      public ContentPageViewModel? ViewModel
 25      {
 26          get => (ContentPageViewModel?)GetValue(ViewModelProperty);
 27          set => SetValue(ViewModelProperty, value);
 28      }
 29  
 30      // Using a DependencyProperty as the backing store for ViewModel.  This enables animation, styling, binding, etc...
 31      public static readonly DependencyProperty ViewModelProperty =
 32          DependencyProperty.Register(nameof(ViewModel), typeof(ContentPageViewModel), typeof(ContentPage), new PropertyMetadata(null));
 33  
 34      public ContentPage()
 35      {
 36          this.InitializeComponent();
 37          this.Unloaded += OnUnloaded;
 38      }
 39  
 40      private void OnUnloaded(object sender, RoutedEventArgs e)
 41      {
 42          // Unhook from everything to ensure nothing can reach us
 43          // between this point and our complete and utter destruction.
 44          WeakReferenceMessenger.Default.UnregisterAll(this);
 45      }
 46  
 47      protected override void OnNavigatedTo(NavigationEventArgs e)
 48      {
 49          if (e.Parameter is not AsyncNavigationRequest navigationRequest)
 50          {
 51              throw new InvalidOperationException($"Invalid navigation parameter: {nameof(e.Parameter)} must be {nameof(AsyncNavigationRequest)}");
 52          }
 53  
 54          if (navigationRequest.TargetViewModel is not ContentPageViewModel contentPageViewModel)
 55          {
 56              throw new InvalidOperationException($"Invalid navigation target: AsyncNavigationRequest.{nameof(AsyncNavigationRequest.TargetViewModel)} must be {nameof(ContentPageViewModel)}");
 57          }
 58  
 59          ViewModel = contentPageViewModel;
 60  
 61          if (!WeakReferenceMessenger.Default.IsRegistered<ActivateSelectedListItemMessage>(this))
 62          {
 63              WeakReferenceMessenger.Default.Register<ActivateSelectedListItemMessage>(this);
 64          }
 65  
 66          if (!WeakReferenceMessenger.Default.IsRegistered<ActivateSecondaryCommandMessage>(this))
 67          {
 68              WeakReferenceMessenger.Default.Register<ActivateSecondaryCommandMessage>(this);
 69          }
 70  
 71          base.OnNavigatedTo(e);
 72      }
 73  
 74      protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
 75      {
 76          base.OnNavigatingFrom(e);
 77          WeakReferenceMessenger.Default.Unregister<ActivateSelectedListItemMessage>(this);
 78          WeakReferenceMessenger.Default.Unregister<ActivateSecondaryCommandMessage>(this);
 79  
 80          // Clean-up event listeners
 81          if (e.NavigationMode != NavigationMode.New)
 82          {
 83              ViewModel?.SafeCleanup();
 84              CleanupHelper.Cleanup(this);
 85          }
 86  
 87          ViewModel = null;
 88      }
 89  
 90      // this comes in on Enter keypresses in the SearchBox
 91      public void Receive(ActivateSelectedListItemMessage message)
 92      {
 93          ViewModel?.InvokePrimaryCommandCommand?.Execute(ViewModel);
 94      }
 95  
 96      // this comes in on Ctrl+Enter keypresses in the SearchBox
 97      public void Receive(ActivateSecondaryCommandMessage message)
 98      {
 99          ViewModel?.InvokeSecondaryCommandCommand?.Execute(ViewModel);
100      }
101  }