2017-02-17 41 views
2

我正在构建一个新的应用程序,在桌面模式下,它很大程度上依赖于具有多个窗口的结构。UWP新应用程序视图

在WPF中,这非常简单易于管理。但在UWP中,由于非常多的mvvm,我几乎放弃了适应不同ui线程的想法。我现在正在做新的构造函数,并处理属性改变了很多地方,我不需要单个UI线程模式。

是否有一些神奇的方式,使应用程序当前UI线程的新应用程序视图?

我希望有一些大师在这里

+0

对,这就是你得到的快速阅读问题。是的,当然,每个'CoreWindow'运行在它自己的线程中,具有自己的输入处理和消息分派。它是在视图内部的'UIElement'的层次结构,它在同一个线程上运行。抱歉。 – IInspectable

+0

我看不到任何理由成为单独的UI线程。 Wpf和winforms在单个UI线程上处理所有这些都很好。我很清楚这个来自其他uwp项目,我只是想知道是否存在一种方法来解决这个问题,而不需要在不同线程之间建立一个层 –

回答

0

这是不可能改变新窗口的线程。

也许你可以使用类似EventAggregator(here's an example from Caliburn.Micro)的东西在Windows之间进行通信? EventAggregator可以帮助隐藏不同线程之间通信的一些细节。

一个想法是,每个窗口创建自己的EventAggregator,但它们拥有一组共享的处理程序/订阅者。与每个用户您存储正确CoreDispatcher:

public class MyEventAggregator 
    { 
     private static List<Tuple<CoreDispatcher, object>> subscribers = new List<Tuple<CoreDispatcher, object>>(); 

     public void Subscribe<TMessage>(ISubscriber<TMessage> subscriber) 
     { 
      subscribers.Add(new Tuple<CoreDispatcher,object>(Window.Current.Dispatcher, subscriber)); 
     } 

所以窗口1创建自己的EventAggregator并订阅作为一名听众:

public sealed partial class MainPage : Page, MainPage.ISubscriber<Message> 
{ 
    public MainPage() 
    { 
     this.InitializeComponent(); 
     var eventAggregator = new MyEventAggregator(); 
     eventAggregator.Subscribe(this); 
    } 

而窗口2创建自己的EventAggregator。窗口2创建使用CoreApplication.CreateNewView()

public sealed partial class Secondary : Page 
{ 
    public MainPage.MyEventAggregator EventAggregator; 

    public Secondary() 
    { 
     this.InitializeComponent(); 
     this.EventAggregator = new MainPage.MyEventAggregator(); 
    } 

请记住,无论是在窗口1和窗口2的EventAggregators有一组共享的用户。

然后,当您想从Window2向Window1发送消息时,您只需调用“发布”即可。此代码是从按钮单击窗口2:

private void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
    { 
     this.EventAggregator.Publish(new Message("hello from second view")); 
    } 

而且EventAggregator可确保窗口1在它自己的UI线程接收消息。所以窗口1可以只更新UI:

public void Handle(Message message) 
    { 
     this.Message.Text = message.Text; 
    } 

这里是一个非常对的点实施方案发布-方法:

 public void Publish<TMessage>(TMessage message) 
     { 
      var messageType = GetEventType(message); 

      foreach (var subscriber in subscribers) 
      { 
       var handler = subscriber.Item2; 

       if (messageType.IsInstanceOfType(handler)) 
       { 
        var dispatcher = subscriber.Item1; 
        dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
        { 
         ((ISubscriber<TMessage>)handler).HandleMessage(message); 
        }); 
       } 
      } 
     } 

     private static Type GetEventType<T>(T args) 
     { 
      return typeof(ISubscriber<>).MakeGenericType(args.GetType()); 
     } 

在现实中,应该确保使用在WeakReferences或其他一些功能来确保GC可以清理事情。

full example of EventAggregator可通过Gist获得。