将 DispatcherHelper 从 MVVMLight 迁移到 Windows Community Toolkit

Ani*_*l C 0 c# wpf .net-4.5 windows-community-toolkit .net-6.0

我正在致力于将基于 .NET 4.5 的 WPF 应用程序升级到 .Net 6。当前应用程序使用的DispatcherHelperWindows Community Toolkit 中不提供该应用程序。我找不到任何示例代码可以帮助我将其替换为 WCT 中可用的代码。我想使用 Windows Community Toolkit 中提供的代码块更新以下代码块:

DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
    this.SelectedControl = new View.MainMenu();
});
Run Code Online (Sandbox Code Playgroud)

DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
     this.SelectedControl = new View.Project();
});
Run Code Online (Sandbox Code Playgroud)

tha*_*guy 9

DispatcherHelper 您可以在此处找到源代码。本质上它的作用是:

  • 检查操作是否有效,否则无效null
  • 检查调用线程是否已经是 UI 线程,如果是,则直接执行操作,否则将其排队等待异步执行。
public static class DispatcherHelper
{
   public static void CheckBeginInvokeOnUI(Action action)
   {
      if (action == null)
         return;

      var dispatcher = Application.Current.Dispatcher;
      if (dispatcher.CheckAccess())
         action();
      else
         dispatcher.BeginInvoke(action);
   }
}
Run Code Online (Sandbox Code Playgroud)

据我所知,DispatcherHelper工具包中只有UWP的替代品,而没有WPF的替代品。您可以像上面那样使用自己的DispatcherHelper类型替换调用,也可以研究该方法的使用地点和上下文。您也可以将调度程序的同步调用替换为Invoke,将异步调用替换为InvokeAsync


上面的版本DispatcherHelper已经切入要点。对于 WPF 来说,完整的内容如下所示。它提供的唯一功能是您可以手动初始化调度程序(加上检查它是否处于活动状态),重置它,以及直接对调度程序上的异步执行操作进行排队,但它可能没有任何用处为你。

public static class DispatcherHelper
{
   public static Dispatcher UIDispatcher { get; private set; }

   public static void CheckBeginInvokeOnUI(Action action)
   {
      if (action == null)
         return;

      CheckDispatcher();

      if (UIDispatcher.CheckAccess())
         action();
      else
         UIDispatcher.BeginInvoke(action);
   }

   private static void CheckDispatcher()
   {
      if (UIDispatcher == null)
         throw new InvalidOperationException("The DispatcherHelper is not initialized.\n" +
                                             "Call DispatcherHelper.Initialize() in the static App constructor.");
   }

   public static DispatcherOperation RunAsync(Action action)
   {
      CheckDispatcher();
      return UIDispatcher.BeginInvoke(action);
   }

   public static void Initialize()
   {
      if (UIDispatcher != null && UIDispatcher.Thread.IsAlive)
         return;

      UIDispatcher = Dispatcher.CurrentDispatcher;
   }

   public static void Reset()
   {
      UIDispatcher = null;
   }
}
Run Code Online (Sandbox Code Playgroud)