【Win10应用开发】自定义磁贴通知的排版

原文:【Win10应用开发】自定义磁贴通知的排版

前面老周用了两篇烂文,向大家介绍了Adaptive磁贴的模板使用。那些XML模板已经很强大了,不过,如果你觉得那些排版还不足以满足需求,不妨试试自己来定义磁贴的内容。

其实,Runtime App支持在后台任务中生成XAML呈现,只要你编写的后台任务类从XamlRenderingBackgroundTask(位于Windows.UI.Xaml.Media.Imaging命名空间)类派生即可。利用这一特性,我们可以在后台生成XAML布局,然后通过RenderTargetBitmap类来呈现XAML内容,再把它保存为图片,最后把保存的图片作为磁贴的背景,就能达到自定义磁贴内容的功效了。

 

第一步,在主应用程序项目中,添加一个XAML文件,因为这个文件不参与编译,也没有对应的Code hide文件,就单个XAML文件即可,实际上是一个文本文件。因此,在生成操作上要设置为“内容”,是否复制到输出目录,选择“不复制”,自定义工具不用填。如图

 

然后你可以自己来设计排版,就和平时用XAML设计界面一样。

<Border
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    BorderThickness="0">
    <Border.Background>
        <ImageBrush AlignmentX="Center" AlignmentY="Center" Stretch="UniformToFill" ImageSource="Assets/1.jpg" />
    </Border.Background>
</Border>

好了,我的界面就这样吧,简单好用。

 

第二步,向解决方案添加一个Windows运行时组件项目,用来在其中定义后台任务类。代码如下:

    public sealed class UpdatetileTask : XamlRenderingBackgroundTask
    {
        protected override async void OnRun(IBackgroundTaskInstance taskInstance)
        {
               ……
         }
    }

注意,这里和以前我们定义普通的后台任务不同,这一次不是实现后台任务接口,而是从XamlRenderingBackgroundTask类派生,然后重写OnRun方法。
里面的处理和一般的后台任务一样了。

1、先要从项目目录加载我们刚才自己定义的那个.xaml文件。

            Border root = new Border();
            Application.LoadComponent(root, new Uri("ms-appx:///customRender.xaml"));
            root.Width = 310;
            root.Height = 150;

LoadComponent是Application类的一个静态方法,直接调用即可,第一个参数是要生成的可视化对象的实例,第二个参数是XAML文件的URI。

我们声明的可视化对象的类型一定要与XAML文档中的根节点的类型匹配,上面在定义XAML文档时,根节点是Border,因此这里声明的变量类型必须为Border,LoadComponent方法调用后,会自动加载并编译XAML文档,然后填充Border变量。

为了让可视化对象能够呈现到位图中,记住要显示设置它的高度和宽度,因为默认情况下Width和Height都为0。

 

2、呈现XAML对象到位图。

            // 将XAML对象呈现到图像中
            RenderTargetBitmap rtb = new RenderTargetBitmap();
            // 因为示例是为宽磁贴生成背景图片的
            // 所以目标的图像大小与宽磁贴相同即可
            // 310 x 150
            await rtb.RenderAsync(root, 310, 150);
            // 取出图像数据
            IBuffer bfData = await rtb.GetPixelsAsync();
            // 将其转换为字节数组
            byte[] data = bfData.ToArray();

3、在本地目录中创建新的PNG文件,并把呈现的XAML内容编码到图像文件中。

            // 在本地目录中创建新的PNG图像文件
            StorageFolder localfd = ApplicationData.Current.LocalFolder;
            StorageFile pngFile = await localfd.CreateFileAsync("bg.png", CreationCollisionOption.ReplaceExisting);
            // 打开文件流
            using (IRandomAccessStream stream = (await pngFile.OpenAsync(FileAccessMode.ReadWrite)))
            {
                // 创建PNG图像编码器
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
                // 设置图像数据
                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)rtb.PixelWidth, (uint)rtb.PixelHeight, 72d, 72d, data);
                await encoder.FlushAsync();
            }

 

4、文件保存后,可以用ms-appdata:///local/开头的URI来访问文件。这时候,我们可以生成磁贴通知的XML文档,并更新磁贴。

            // 组创XML文档
            string xml = "<tile>" +
                            "<visual>" +
                                "<binding template=\"TileWide\">" +
                                    "<image src=\"ms-appdata:///local/bg.png\" placement=\"background\" />" +
                                "</binding>"   +
                             "</visual>" +
                         "</tile>";
            // 创建XML文档
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            // 更新磁贴通知
            TileNotification notification = new TileNotification(doc);
            TileUpdater updater = TileUpdateManager.CreateTileUpdaterForApplication();
            updater.Update(notification);

 

 

第三步,在主应用程序中引用刚才的后台任务项目。然后配置一下清单文件,在正式版的SDK中,已经可以使用图形化的清单编辑器了,可以直接操作。

添加一个后台任务声明,类型为“常规”。

填上后台任务类的入口点,即类名,要包括命名空间的名字。

 

第四步,在前台代码中注册后台任务。前面的文章中,老周给大家介绍过可以通ApplicationTrigger直接在应用程序中触发后台任务,所以本示例我就用它了。

            var res = await BackgroundExecutionManager.RequestAccessAsync();
            if (res == BackgroundAccessStatus.Denied || res == BackgroundAccessStatus.Unspecified)
            {
                Debug.WriteLine("后台任务被禁用。"); return;
            }

            // 考虑注册后台任务
            BackgroundTaskRegistration reg = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault(t => t.Name == TASK_NAME) as BackgroundTaskRegistration;

            if (reg == null)
            {
                BackgroundTaskBuilder bd = new BackgroundTaskBuilder();
                bd.Name = TASK_NAME;
                bd.TaskEntryPoint = typeof(backUpdater.UpdatetileTask).FullName;
                ApplicationTrigger trigger = new ApplicationTrigger();
                bd.SetTrigger(trigger);
                reg = bd.Register();
            }

 

最后,我们可以在代码中手动触发这个后台。

            BackgroundTaskRegistration reg = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault(t => t.Name == TASK_NAME) as BackgroundTaskRegistration;
            if (reg == null)
            {
                return;
            }

            ApplicationTrigger trigger = reg.Trigger as ApplicationTrigger;
            await trigger.RequestAsync();

 

运行应用程序后,把程序固定到开始屏幕,并把图标改为宽磁贴,然后回到应用程序,触发后台,更新磁贴。

唉,天天写代码很枯燥,很无聊?没事,一起来坐在桃花底下读读《西厢记》,就会好的了。

 

OK,今天的牛皮暂时吹到这里。

例子源代码下载:http://files.cnblogs.com/files/tcjiaan/customTileUpdateApp.zip

 

时间: 2024-08-03 04:05:47

【Win10应用开发】自定义磁贴通知的排版的相关文章

Win10 应用开发中Toast通知的XML文档结构教程

在以前8.1时候的Toast通知方式,到了Win 10中依然支持,而且UWP API中也包括了对应的API协定.所以,你仍然可以使用8.1的通知方式,即通过ToastNotificationManager.GetTemplateContent(ToastTemplateType)方法来获取对应的通知模板,然后用XmlDocument对象来加载和修改XML,当然你也可以直接构造XML文档,然后用XmlDocument对象来加载. 还有就是操作中心,其实它和Toast是一伙的,即我们不需要用专门的A

【Win10 应用开发】自适应Toast通知的XML文档结构

原文:[Win10 应用开发]自适应Toast通知的XML文档结构 老规矩,在开始之前老周先讲个故事. 话说公元2015年7月20日,VS 2015发布.于是,肯定有人会问老周了,C#6有啥新特性,我学不来啊.学不来的话你应该检讨.老周比较保守地计算一下,学会C# 6只需要20秒,不信的话,老周笔划笔划一下,你就明白了.   1.属性自动初始化.在4.0中引入了这样声明属性: public int VVVV { get; set;} 以前是属性包装一个字段,在初始化属性时只要对字段赋值即可,这个

【Win10应用开发】协议-下篇:自定义多个协议

原文:[Win10应用开发]协议-下篇:自定义多个协议 前面介绍了如何为应用程序自定义协议,于是有朋友会问,我希望为我的应用注册多个协议,不同的协议处理不同的事情,能吗?答案是能的. 方法主要在配置清单文件上,这里我给出一个例子,示例应用将注册两个协议,分别为music:和video:. 在清单文件中找到Package/Applications/Application节点,在Application元素下增加Extensions节点,表示为应用程序声明的扩展,可以包含N个uap:Extension

【Win10应用开发】自适应磁贴中的分组

原文:[Win10应用开发]自适应磁贴中的分组 老周在上一篇文章中介绍过了自适应磁贴的基本结构,以及给大家演示了一些例子. 本文老周给大伙伴们说说自适应磁贴的另一个特点--分组呈现. 当磁贴的内容被分组后,每个组中的内容就会被视为一个整体.比如某磁贴在更新时定义了其内容包含有两个组,有些设备(比如手机.上世纪70年代的电脑.小霸王学习机等)的分辨率较低,磁贴不能显示两个组的信息,于是就会把第一组的内容整个显示出来,第二组信息就被忽略.就算空间不够,连第一组的内容都显示不全,然而一个组会被视为一个

【Win10应用开发】自定义桌面壁纸

原文:[Win10应用开发]自定义桌面壁纸 调用通用的API来设置桌面壁纸,是一件既简单又有趣的事情,结合XAML可以生成图像的特性,你甚至可以做一个应用,让用户用他所拍的照片做成一张自定义壁纸,然后作为桌面壁纸. 这个API是通用的,应用运行在任意Windows设备上都能使用,当然包括手机.在Windows.System.UserProfile命名空间下,有一个叫UserProfilePersonalizationSettings的类,它可以修改锁屏壁纸和桌面壁纸,调用后会返回bool值,如果

【Win10应用开发】自定义打印选项

原文:[Win10应用开发]自定义打印选项 老周在前一篇烂文中已经给大伙伴们演示了如何打印UI元素,今天的烂文就向各位介绍一下,如何向打印对话框添加自定义选项.如果只是讲如何实现,会比较抽象,也比较枯燥,而且相当无聊,更是说不清楚,毕竟这打印API用起来要比其他API稍稍复杂了一点.所以老周就做了一个打印图片的垃圾应用,在打印对话框中,你可以选择设置要打印图片的不透明度.旋转角度(0度,90度,180度,270度). OK,为环保事业做贡献,老周今天也节约一点口水.下面咱们开始干活. 1.先来设

Windows Phone开发(44):推送通知第二集——磁贴通知

原文:Windows Phone开发(44):推送通知第二集--磁贴通知 前面我们说了第一个类型--Toast通知,这玩意儿不知大家是不是觉得很新鲜,以前玩.NET编程应该没接触过吧? 其实这东西绝对不复杂,只是刚接触的时候会有点莫名罢了,Toast通知和今天要说的磁贴通知,都有一个共同点,那就是格式都规定死了D. 本质就是向特定的URI地址POST一个XML文档罢了,相信很多人都会,如果你还不会,真的,要补一补基础课了.  多说无益,还是快点切入主题,开门见水吧. 首先,我们要知道我们在服务器

Visual C++2005中开发自定义绘图控件

本文源代码下载:CustomDraw.exe. 在您决定开发 Windows 提供的常规免费自定义控件范围之外的控件之后,您必需确定自己的控件将有多少独到之处 - 在功能和外观两方面.例如,我们假定您正在创建一个类似于计速表的控件.由于公共控件库 (ComCtrl32.dll) 中没有类似的控件,您完全需要自己进行以下操作:编写所有控件功能需要的代码,进行绘制,默认终端用户的交互,以及控件与其父窗口之间需要的任意消息处理. 另一方面,还包括一些您只想调整公共控件功能的情况.例如,我们假定您想创建

Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

原文:Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App 安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneGap.ionic.AngularJS这些框架或库的关系,我个人理解是这样,PhoneGap是一个商业项目,用来实现HTML5式的跨平台开发,后来Adobe公司将其中的核心代码开源,就是Co