UWP中的Attached Property即附加属性,在实际开发中是很常见的,比如Grid.Row:

  1. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  2. <Grid.RowDefinitions>
  3. <RowDefinition></RowDefinition>
  4. <RowDefinition></RowDefinition>
  5. </Grid.RowDefinitions>
  6. <Button Grid.Row="1"></Button>
  7. </Grid>

  Grid.Row这个属性并不是Button对象本身的实例方法,而是定义在Grid类型上的static property,实际使用时却又附在其他控件的XAML里。

  我们今天不讨论如何使用UWP中已经定义好的Attached Property(使用起来很简单,没啥好讲的),也不会介绍附件属性的定义,以及与.NET属性的区别(MSDN文档非常详细),更不会花大力气去分析附加属性背后的原理(这个有大牛珠玉在前,不敢造次)。

  本篇仅以极简单的例子来展示Attached Propery的应用场景,抛砖引玉以期共同学习提高。

  设想场景如下,需要根据文本内容,将电话号码和邮箱地址以下划线蓝色字体和普通文本区分开来:

  

  1. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  2. <TextBlock local:RichTextBlockEx.RichText="种子我发你这个邮箱:SampleEmail@outlook.com,有事打我电话18610241024。"></TextBlock>
  3. </Grid>

  显示文本UWP中一般是通过TextBlock来实现,一段文字中如果需要不同颜色,以及增加下划线就需要在TextBlock的Inlines属性中添加不同的Inline的子类对象(比如Run,Underline等)。

  而修改TextBlock的Inlines集合需要直接操作TextBlock对象,UWP的程序又通常是MVVM结构,在ViewModel中不应添加对View层级的引用,这就要求不能在ViewModel中访问TextBlock。

  那么修改TextBlock的逻辑就只能放在View中,问题是最终返回的TextBlock需要根据运行时具体绑定的文本内容才能确定,要求同时能访问TextBlock以及绑定的DataContext。似乎也不适合写在Page.xaml.cs中。

  Attached Propery则非常完美的解决了我们的问题,首先附加属性支持binding,这就将View中的TextBlock和ViewModel中的文本内容结合在一起;其次附加属性是View层级的概念,通过它来修改TextBlock不会破坏MVVM的结构。

  接下来我们动手定义一个Attached Property:

  1. public static string GetRichText(DependencyObject obj)
  2. {
  3. return (string)obj.GetValue(RichTextProperty);
  4. }
  5.  
  6. public static void SetRichText(DependencyObject obj, string value)
  7. {
  8. obj.SetValue(RichTextProperty, value);
  9. }
  10.  
  11. // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
  12. public static readonly DependencyProperty RichTextProperty =
  13. DependencyProperty.RegisterAttached("RichText", typeof(string), typeof(RichTextBlockEx), new PropertyMetadata(null, RichTextChanged));

  这个附加属性叫做RichTextProperty,我们给他做了GetRichText和SetRichText两个方法的封装,以便我们能像经典的.NET属性一样,通过“RichText”来访问。具体的细节请参考MSDN的文档,这里我们着重看一下RegisterAttached方法中传递了一个回调方法RichTextChanged。

  1. private static void RichTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  2. {
  3. TextBlock textBlock = d as TextBlock;
  4. if (textBlock == null)
  5. return;
  6. string inputString = e.NewValue as string;
  7. if (string.IsNullOrEmpty(inputString) || string.IsNullOrWhiteSpace(inputString))
  8. {
  9. textBlock.Text = string.Empty;
  10. return;
  11. }
  12. textBlock.Inlines.Clear();
  13. CreateTextBlock(textBlock, inputString);
  14. }

  该方法是一个静态方法,在biding的对象发生改变时触发,并将biding的对象本身作为第一个参数传递进来。该方法的代码先判断了绑定的新值是否为空,不为空则调用CreateTextBlock方法,根据inputString来创建带有蓝色下划线的TextBlock。

  1. private static void CreateTextBlock(TextBlock textBlock, string inputString)
  2. {
  3. var resultList = new List<MatchResult>();
  4. resultList.AddRange(GetMatchResultList(inputString));
  5.  
  6. int offset = ;
  7. var matchDicOrder = resultList.OrderBy(_ => _.Match.Index);
  8. foreach (var item in matchDicOrder)
  9. {
  10. var match = item.Match;
  11. if (match.Index >= offset)
  12. {
  13. if (match.Index > && match.Index != offset)
  14. {
  15. var text = inputString.Substring(offset, match.Index - offset);
  16. AddText(textBlock, text);
  17. }
  18.  
  19. var content = inputString.Substring(match.Index, match.Length);
  20. AddUnderline(textBlock, content);
  21. offset = match.Index + match.Length;
  22. }
  23. }
  24.  
  25. if (offset < inputString.Length)
  26. {
  27. var text = inputString.Substring(offset);
  28. AddText(textBlock, text);
  29. }
  30. }

  通过正则表达式匹配phone和email,将匹配的内容通过AddUnderline方法添加到原TextBlock中,不匹配的内容则直接AddText。

  1. private static void AddText(TextBlock textBlock, string text)
  2. {
  3. Run run = new Run();
  4. run.Text = text;
  5. textBlock.Inlines.Add(run);
  6. }
  7.  
  8. private static void AddUnderline(TextBlock textBlock, string content)
  9. {
  10. Run run = new Run();
  11. run.Text = content;
  12. run.Foreground = new SolidColorBrush(Colors.Blue);
  13. Underline underline = new Underline();
  14. underline.Inlines.Add(run);
  15.  
  16. textBlock.Inlines.Add(underline);
  17. }

  实际的开发中,这里可能存在更复杂的逻辑,比如即时通讯程序中存在@的概念,下划线的内容需要在点击后做相应处理等(打电话,发邮件)。本篇中的代码为了简单清晰做了最简化的处理,各位在自己的APP里可以进一步发挥想象补充,只要别让手机或电脑爆炸就行……

  本篇有心回归开发入门的初心,介绍的内容较为简单,写得不好还请包涵。

  照例放出GayHub地址:

  https://github.com/manupstairs/UWPSamples

UWP开发入门(十一)——Attached Property的简单应用的更多相关文章

  1. UWP开发入门(十六)——常见的内存泄漏的原因

    本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏>中提到过,即使有 ...

  2. UWP开发入门系列笔记之(一):UWP初览

    标签: 随着微软Build2015带来的好消息,Win10正式版发布的日子已经离我们越来越近了,我们也终于欣喜地看到:一个统一的Windows平台对于开发人员来说充满了吸引力,这局棋下的好大的说--于 ...

  3. UWP开发入门(四)——自定义CommandBar

    各位好,再次回到UWP开发入门系列,刚回归可能有些不适应,所以今天我们讲个简单的,自定义CommandBar,说通俗点就是自定义类似AppBarButton的东西,然后扔到CommandBar中使用. ...

  4. UWP开发入门(25)——通过Radio控制Bluetooth, WiFi

    回顾写了许久的UWP开发入门,竟然没有讲过通过Windows.Devices.Radios.Radio来控制Bluetooth和WiFi等功能的开关.也许是因为相关的API设计的简单好用,以至于被我给 ...

  5. UWP开发入门(十)——通过继承来扩展ListView

    本篇之所以起这样一个名字,是因为重点并非如何自定义控件,不涉及创建CustomControl和UserControl使用的Template和XAML概念.而是通过继承的方法来扩展一个现有的类,在继承的 ...

  6. uwp开发:数据绑定——值转换器 的简单使用

    原文:uwp开发:数据绑定--值转换器 的简单使用 今天,我在做最近正在开发的“简影”uwp应用时遇到一个问题,其中有个栏目,叫做“画报”,是分组显示一组一组的 图片,每组图片在界面上只显示9个,点击 ...

  7. 【转载】salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建

    salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建   VisualForce封装了很多的标签用来进行页面设计,本篇主要讲述简单的页面增删改查.使用的内容和设计到前台页面使用的 ...

  8. UWP开发入门(二十一)——保持Ui线程处于响应状态

    GUI的程序有时候会因为等待一个耗时操作完成,导致界面卡死.本篇我们就UWP开发中可能遇到的情况,来讨论如何优化处理. 假设当前存在点击按钮跳转页面的操作,通过按钮打开的新页面,在初始化过程中存在一些 ...

  9. UWP开发入门(七)——下拉刷新

    本篇意在给这几天Win10 Mobile负面新闻不断的某软洗地,想要证明实现一个简单的下拉刷新并不困难.UWP开发更大的困难在于懒惰,缺乏学习的意愿.而不是“某软连下拉刷新控件都没有”这样的想法. 之 ...

随机推荐

  1. 实用的插件:跨浏览器复制jQuery-zclip

    Query-zclip是一个复制内容到剪贴板的jQuery插件,使用它我们不用考虑不同浏览器和浏览器版本之间的兼容问题.jQuery-zclip插件需要Flash的支持,使用时记得安装Adobe Fl ...

  2. Ubuntu上安装和使用SSH,Xming+PuTTY在Windows下远程Linux主机使用图形界面的程序

    自:http://blog.csdn.net/neofung/article/details/6574002 Ubuntu上安装和使用SSH  网上有很多介绍在Ubuntu下开启SSH服务的文章,但大 ...

  3. Maven - 项目结构

    一个基础的Maven Java项目结构图如下所示: Project Name |__________ pom.xml |__________ src |                     |__ ...

  4. ambari初始化登陆账号/密码假如不是admin/admin

    如题:通常软件初始化密码都是admin: 但是hortonworks就突然傻逼了,居然不这样搞.(可能知道一些开发者不看官网文档,就特意弄成这样.正如我) 我上网搜了5分钟.感觉网上应该没有这样的资料 ...

  5. 深入剖析 redis AOF 持久化策略

    本篇主要讲的是 AOF 持久化,了解 AOF 的数据组织方式和运作机制.redis 主要在 aof.c 中实现 AOF 的操作. 数据结构 rio redis AOF 持久化同样借助了 struct ...

  6. 生活科技两相宜:(一)Win7使用微软SkyDrive网盘简易教程

    今天得写一个Win7使用微软SkyDrive网盘的简易教程,主要是给我老婆看,顺便贴出来给大家共享一下:)    使用微软SkyDrive网盘有两个层次.一个是使用网页版,这个跟使用163或者QQ网盘 ...

  7. [GraphQL] Serve a GraphQL Schema as Middleware in Express

    If we have a GraphQL Schema expressed in terms of JavaScript, then we have a convenient package avai ...

  8. 读Java 804 - Quick refresher

    Upcast永远是成功的,但Downcast不是,记得做instanceof判断 仅抛不同异常,而返回值相同的重载是不可以的 static import只会import静态类 static metho ...

  9. 给The Lab Renderer for Unity中地形添加阴影

    The Lab Renderer for Unity是Valve针对VR在Unity的体验渲染器,提高VR的渲染效率,更多的大家可以查相应资料,在这,说个The Lab Renderer for Un ...

  10. 出现Assertion failure in -[***** layoutSublayersOfLayer:]

    在自定义的view中使用了[self layoutIfNeeded]方法,在iOS8\9上都没有错误,但是在iOS7上出现了页面错乱,解决方案就是在自定义的view里面添加如下代码: + (void) ...