我正在构建一个新应用,该应用在桌面模式下严重依赖于具有多个窗口的结构。

在WPF中,这非常易于管理。但是在UWP中,由于非常多的mvvm,我几乎无法适应不同的ui线程。我现在正在使新的构造函数和处理的propertychanged改变了很多我在单ui线程模式下不需要的地方。

有什么神奇的方法可以在应用程序当前的ui线程上创建新的applicationview?

我希望这里有一些大师

最佳答案

无法更改新窗口的线程。

也许您可以使用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));
        }


因此,Window1创建自己的EventAggregator并订阅为侦听器:

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


然后Window2创建自己的EventAggregator。 Window2是使用CoreApplication.CreateNewView()创建的:

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

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


请记住,Window1和Window2中的EventAggregators都有一组共享的订户。

然后,当您要将消息从Window2发送到Window1时,只需调用发布。这段代码来自Window2中的按钮单击:

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


并且EventAggregator确保Window1在其自己的UI线程中接收到消息。所以Window1可以只更新UI:

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


这是Publish方法的真正重点:

        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获得。

关于c# - UWP新应用程序 View ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42303106/

10-12 12:45