2017-02-17 42 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獲得。