zoukankan      html  css  js  c++  java
  • 背水一战 Windows 10 (4)

    [源码下载]


    背水一战 Windows 10 (4) - UI: 多窗口



    作者:webabcd


    介绍
    背水一战 Windows 10 之 UI

    • 多窗口



    示例
    1、自定义帮助类,用于简化 SecondaryView 的管理
    UI/MultipleViews/SecondaryViewHelper.cs

    /*
     * SecondaryViewHelper - 自定义的一个帮助类,用于简化 SecondaryView 的管理
     */
    
    using System;
    using System.ComponentModel;
    using Windows.UI.Core;
    using Windows.UI.ViewManagement;
    
    namespace Windows10.UI.MultipleViews
    {
        public class SecondaryViewHelper : INotifyPropertyChanged
        {
            // for INotifyPropertyChanged
            public event PropertyChangedEventHandler PropertyChanged;
    
            // 当前 SecondaryView 的 CoreDispatcher
            private CoreDispatcher _dispatcher;
            // 当前 SecondaryView 的 ApplicationView
            private ApplicationView _applicationView;
    
            // 当前 SecondaryView 的标题
            private string _title;
            // 当前 SecondaryView 的窗口标识
            private int _viewId;
    
            // 当前 SecondaryView 被引用的次数
            private int _refCount = 0;
            // 当前 SecondaryView 是否已经被释放
            private bool _released = false;
    
            // 禁止通过 new 实例化
            private SecondaryViewHelper(CoreWindow newWindow)
            {
                _dispatcher = newWindow.Dispatcher;
                _viewId = ApplicationView.GetApplicationViewIdForWindow(newWindow);
    
                _applicationView = ApplicationView.GetForCurrentView();
    
                RegisterForEvents();
            }
    
            // 实例化 SecondaryViewHelper
            public static SecondaryViewHelper CreateForCurrentView()
            {
                /*
                 * CoreWindow.GetForCurrentThread() - 获取当前窗口的 CoreWindow
                 */
                return new SecondaryViewHelper(CoreWindow.GetForCurrentThread());
            }
            private void RegisterForEvents()
            {
                /*
                 * ApplicationView.GetForCurrentView() - 获取当前窗口的 ApplicationView
                 * ApplicationView.Consolidated - 当前 app 存活着两个或两个以上的窗口时,此窗口关闭后触发的事件
                 */
                ApplicationView.GetForCurrentView().Consolidated += SecondaryViewHelper_Consolidated;
            }
    
            private void UnregisterForEvents()
            {
                ApplicationView.GetForCurrentView().Consolidated -= SecondaryViewHelper_Consolidated;
            }
    
            private void SecondaryViewHelper_Consolidated(ApplicationView sender, ApplicationViewConsolidatedEventArgs args)
            {
                StopViewInUse();
            }
    
            // 当前 SecondaryView 开始使用了(与 StopViewInUse() 成对)
            // 因为每一个窗口都可以被同 app 的别的窗口调用,而每一个窗口又都是一个独立的线程,所以要做好线程处理
            public int StartViewInUse()
            {
                bool releasedCopy = false;
                int refCountCopy = 0;
    
                lock (this)
                {
                    releasedCopy =_released;
                    if (!_released)
                    {
                        refCountCopy = ++_refCount;
                    }
                }
    
                if (releasedCopy)
                {
                    throw new InvalidOperationException("this view is being disposed");
                }
    
                return refCountCopy;
            }
    
            // 当前 SecondaryView 结束使用了(与 StartViewInUse() 成对)
            // 因为每一个窗口都可以被同 app 的别的窗口调用,而每一个窗口又都是一个独立的线程,所以要做好线程处理
            public int StopViewInUse()
            {
                int refCountCopy = 0;
                bool releasedCopy = false;
    
                lock (this)
                {
                    releasedCopy = _released;
                    if (!_released)
                    {
                        refCountCopy = --_refCount;
                        if (refCountCopy == 0)
                        {
                            // 当前 SecondaryView 不再被任何人需要了,清理之
                            var task = _dispatcher.RunAsync(CoreDispatcherPriority.Low, FinalizeRelease);
                        }
                    }
                }
    
                if (releasedCopy)
                {
                    throw new InvalidOperationException("this view is being disposed");
                }
    
                return refCountCopy;
            }
    
            // 清理当前 SecondaryView
            private void FinalizeRelease()
            {
                bool justReleased = false;
                lock (this)
                {
                    if (_refCount == 0)
                    {
                        justReleased = true;
                        _released = true;
                    }
                }
    
                if (justReleased)
                {
                    UnregisterForEvents();
    
                    // 触发 Released 事件
                    OnReleased(EventArgs.Empty);
                }
            }
    
            // 定义 Released 事件
            public event EventHandler<EventArgs> Released;
            protected virtual void OnReleased(EventArgs e)
            {
                EventHandler<EventArgs> handler = Released;
                if (handler != null)
                    handler(this, e);
            }
    
            public int Id
            {
                get
                {
                    return _viewId;
                }
            }
    
            public string Title
            {
                get
                {
                    return _title;
                }
                set
                {
                    if (_title != value)
                    {
                        _title = value;
    
                        if (PropertyChanged != null)
                        {
                            PropertyChanged(this, new PropertyChangedEventArgs(nameof(Title)));
                        }
                    }
                }
            }
    
            public bool IsReleased
            {
                get
                {
                    return _released;
                }
            }
    
            public ApplicationView ApplicationView
            {
                get
                {
                    return _applicationView;
                }
            }
        }
    }


    2、扩展 Application 对象,定义一些需要用到的全局变量
    UI/MultipleViews/AppPartial.cs

    /*
     * 扩展 Application 对象,定义一些需要用到的全局变量
     */
    
    using Windows.ApplicationModel.Activation;
    using Windows.UI.Core;
    using Windows.UI.ViewManagement;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace Windows10
    {
        public partial class App
        {
            // PrimaryView 的 CoreDispatcher
            private CoreDispatcher _mainDispatcher;
            // PrimaryView 的窗口标识
            private int _mainViewId;
    
            // partial method,实现了 App.xaml.cs 中的声明
            partial void OnLaunched_MultipleViews(LaunchActivatedEventArgs args)
            {
                _mainDispatcher = Window.Current.Dispatcher;
                _mainViewId = ApplicationView.GetForCurrentView().Id;
            }
            
            public CoreDispatcher MainDispatcher
            {
                get
                {
                    return _mainDispatcher;
                }
            }
            
            public int MainViewId
            {
                get
                {
                    return _mainViewId;
                }
            }
        }
    }


    3、用于演示 SecondaryView 的示例
    UI/MultipleViews/SecondaryViewPage.xaml

    <Page
        x:Class="Windows10.UI.MultipleViews.SecondaryViewPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.UI.MultipleViews"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="10 0 10 10">
    
                <TextBlock Name="lblMsg" Margin="0 10 0 0" />
    
                <Button Name="btnGoToMain" Content="切换到主窗口" Click="btnGoToMain_Click" Margin="0 10 0 0" />
    
                <Button Name="btnGoToMainAndHideThisView" Content="切换到主窗口,并关闭此窗口" Click="btnGoToMainAndHideThisView_Click" Margin="0 10 0 0" />
    
            </StackPanel>
        </Grid>
    </Page>

    UI/MultipleViews/SecondaryViewPage.xaml.cs

    /*
     * 演示“多窗口”相关知识点。本页是 SecondaryView
     */
    
    using System;
    using System.ComponentModel;
    using Windows.ApplicationModel.Core;
    using Windows.UI.Core;
    using Windows.UI.ViewManagement;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace Windows10.UI.MultipleViews
    {
        public sealed partial class SecondaryViewPage : Page
        {
            private SecondaryViewHelper _secondaryViewHelper;
    
            public SecondaryViewPage()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                _secondaryViewHelper = (SecondaryViewHelper)e.Parameter;
                _secondaryViewHelper.Released += _secondaryViewHelper_Released;
    
                // 设置当前窗口的 Title
                ApplicationView.GetForCurrentView().Title = _secondaryViewHelper.Title;
                _secondaryViewHelper.PropertyChanged += _secondaryViewHelper_PropertyChanged;
            }
    
            private void _secondaryViewHelper_PropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                if (e.PropertyName == nameof(_secondaryViewHelper.Title))
                {
                    _secondaryViewHelper.ApplicationView.Title = _secondaryViewHelper.Title;
                }
            }
    
            private async void _secondaryViewHelper_Released(object sender, EventArgs e)
            {
                ((SecondaryViewHelper)sender).Released -= _secondaryViewHelper_Released;
    
                await ((App)App.Current).MainDispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    // 调用主窗口线程,执行逻辑
                });
    
                Window.Current.Close();
            }
    
            private async void btnGoToMain_Click(object sender, RoutedEventArgs e)
            {
                _secondaryViewHelper.StartViewInUse();
    
                /*
                 * ApplicationViewSwitcher.SwitchAsync() - 切换到指定的窗口
                 */
                await ApplicationViewSwitcher.SwitchAsync
                (
                    ((App)App.Current).MainViewId // 准备显示的窗口的 id
                );
    
                _secondaryViewHelper.StopViewInUse();
            }
    
            private async void btnGoToMainAndHideThisView_Click(object sender, RoutedEventArgs e)
            {
                _secondaryViewHelper.StartViewInUse();
    
                /*
                 * ApplicationViewSwitcher.SwitchAsync() - 切换到指定的窗口
                 */
                await ApplicationViewSwitcher.SwitchAsync
                (
                    ((App)App.Current).MainViewId, // 准备显示的窗口的 id
                    ApplicationView.GetForCurrentView().Id, // 调用者的窗口 id
                    ApplicationViewSwitchingOptions.ConsolidateViews // 切换行为选项(Default - 标准动画切换; SkipAnimation - 不使用动画切换; ConsolidateViews - 切换后关闭调用者窗口)
                );
    
                _secondaryViewHelper.StopViewInUse();
            }
        }
    }


    4、用于演示 PrimaryView 的示例
    UI/MultipleViews/Demo.xaml

    <Page
        x:Class="Windows10.UI.MultipleViews.Demo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.UI.MultipleViews"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="10 0 10 10">
    
                <TextBlock Name="lblMsg" Margin="0 10 0 0" />
    
                <Button Name="btnShow" Content="创建并显示一个新的窗口" Click="btnShow_Click" Margin="0 10 0 0" />
    
                <Button Name="btnChangeLastSecondaryViewTitle" Content="修改最近一个被我打开的 SecondaryView 的 Title" Click="btnChangeLastSecondaryViewTitle_Click" Margin="0 10 0 0" />
    
            </StackPanel>
        </Grid>
    </Page>

    UI/MultipleViews/Demo.xaml.cs

    /*
     * 演示“多窗口”相关知识点。本页是 PrimaryView
     *
     *
     * 解释一下本例中用于说明的几个名词:PrimaryView - 主窗口; SecondaryView - 新开窗口
     */
    
    using System;
    using Windows.ApplicationModel.Core;
    using Windows.UI.Core;
    using Windows.UI.ViewManagement;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace Windows10.UI.MultipleViews
    {
        public sealed partial class Demo : Page
        {
            // 自定义的用于简化 SecondaryView 管理的帮助类
            SecondaryViewHelper _secondaryViewHelper = null;
    
            public Demo()
            {
                this.InitializeComponent();
    
                this.Loaded += Demo_Loaded;
            }
    
            private void Demo_Loaded(object sender, RoutedEventArgs e)
            {
                ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto;
            }
    
            private async void btnShow_Click(object sender, RoutedEventArgs e)
            {
                /*
                 * CoreApplication.CreateNewView() - 创建一个新的 SecondaryView(只是新建一个 SecondaryView 实例,并不会显示出来)
                 */
                await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    _secondaryViewHelper = SecondaryViewHelper.CreateForCurrentView();
                    _secondaryViewHelper.Title = "i am secondary view";
    
                    _secondaryViewHelper.StartViewInUse();
    
                    var frame = new Frame();
                    frame.Navigate(typeof(SecondaryViewPage), _secondaryViewHelper);
                    Window.Current.Content = frame;
                    Window.Current.Activate();
    
                    // 这里通过 ApplicationView.GetForCurrentView() 获取到的是新开窗口的 ApplicationView 对象
                    ApplicationView secondaryView = ApplicationView.GetForCurrentView();
                });
    
                try
                {
                    _secondaryViewHelper.StartViewInUse();
    
                    /*
                     * ApplicationViewSwitcher.TryShowAsStandaloneAsync() - 在当前窗口的相邻位置显示另一个窗口
                     */
                    ApplicationViewSwitcher.DisableShowingMainViewOnActivation();
                    var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync
                    (
                        _secondaryViewHelper.Id, // 需要显示的 SecondaryView 的窗口 id
                        ViewSizePreference.Default, // 需要显示的 SecondaryView 的尺寸首选项(经测试,此参数无效)
                        ApplicationView.GetForCurrentView().Id, // 调用者的窗口 id
                        ViewSizePreference.Default // 调用者的尺寸首选项(经测试,此参数无效)
                    );
    
                    if (!viewShown)
                    {
                        lblMsg.Text = "显示 SecondaryView 失败";
                    }
    
                    _secondaryViewHelper.StopViewInUse();
                }
                catch (Exception ex)
                {
                    lblMsg.Text = ex.ToString();
                }
            }
    
            // 修改最近一个被我打开的 SecondaryView 的 Title
            private void btnChangeLastSecondaryViewTitle_Click(object sender, RoutedEventArgs e)
            {
                if (_secondaryViewHelper != null && !_secondaryViewHelper.IsReleased)
                    _secondaryViewHelper.Title = new Random().Next().ToString();
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    zookeeper使用场景
    zookeeper安装配置
    hadoop 远程调试
    deep learning笔记
    Sentiment Analysis(1)-Dependency Tree-based Sentiment Classification using CRFs with Hidden Variables
    PRML阅读笔记 introduction
    Python 学习笔记(2)
    python nltk 学习笔记(5) Learning to Classify Text
    python nltk 学习笔记(4) Writing Structured Programs
    python nltk 学习笔记(3) processing raw text
  • 原文地址:https://www.cnblogs.com/webabcd/p/5318129.html
Copyright © 2011-2022 走看看