UWP: 妙用自定义 Action 以简化并重用代码

简介: 原文:UWP: 妙用自定义 Action 以简化并重用代码    相信每一位 App 开发者,在开发过程中,都会有一些代码被反复用到,比如:复制文本,打电话,发短信,发邮件,给应用添加评论等等。在项目之间复制这些代码段,实在不是一个好办法,所以大家可能会把这些代码放到一个类似 Utility 类中,或者一个库(Class Library)中,再加以调用。
原文: UWP: 妙用自定义 Action 以简化并重用代码

    相信每一位 App 开发者,在开发过程中,都会有一些代码被反复用到,比如:复制文本,打电话,发短信,发邮件,给应用添加评论等等。在项目之间复制这些代码段,实在不是一个好办法,所以大家可能会把这些代码放到一个类似 Utility 类中,或者一个库(Class Library)中,再加以调用。本文也是帮你完成同样的事情,不过本文是通过 Action 来完成。这两种方法的目的相同,区别是前者尽管实现了代码段封装,还是需要写代码(通常在 ViewModel 中)来调用,而后者,则只要在 XAML 上添加几行代码即可。相比而言,后者要更为方便一些。

    这里的 Action 是来自 Behaviors SDK 里的概念,其实就是一个实现了 IAction 接口的类。我在本文不会介绍关于 Behaviors SDK 的基本知识,如果你对于它还不够了解,可以在园子里搜索一下相关文章,加以学习(在本文最后的参考文章处,我已经列了一篇比较不错的文章)。

    本质上, Action 与 Behavior 有着相同的目的,它们都是可以重用的一段代码。在它所实现的 IAction 接口中,定义了一个 Execute 方法,这个方法会在满足条件时被执行,条件可能是控件的事件被触发,或者属性发生改变等等。在 Execute 方法中,我们可以调用那些能完成我们想要的任务的方法。

    为了完成前面所述的需求,我们首先新建一个 UWP 项目并为其添加 Behavior SDK 引用(这个项目主要是为测试后面创建的 Action)。

    新建一个名为 CommonTaskAction 的类,此类实现了 IAction 接口,并且我们使它继承自 DependencyObject 类,这样我们可以为它定义依赖属性,以实现在 XAML 中可通过 Binding 向其赋值。如下:

public class CommonTaskAction : DependencyObject, IAction
{
        public object Execute(object sender, object parameter)
        {

} }

    然后,定义一个枚举,用来表达常见任务类型,如下:

    public enum CommonTaskType
    {
        /// <summary>
        /// 复制文本
        /// </summary>
        CopyText,
        /// <summary>
        /// 打电话
        /// </summary>
        MakePhoneCall,
    }

    接着,为 CommonTaskAction 类添加几个依赖属性:TaskType(任务类型),TextToBeCopied(待复制的文本),PhoneNO(电话号码),PhoneDisplayName(打电话时的显示名称),如下:

        public static readonly DependencyProperty PhoneDisplayNameProperty =
            DependencyProperty.Register("PhoneDisplayName", typeof(string), typeof(CommonTaskAction), new PropertyMetadata(string.Empty));

        
        public static readonly DependencyProperty PhoneNOProperty =
            DependencyProperty.Register("PhoneNO", typeof(string), typeof(CommonTaskAction), new PropertyMetadata(string.Empty));

        
        public static readonly DependencyProperty TaskTypeProperty =
            DependencyProperty.Register("TaskType", typeof(CommonTaskType), typeof(CommonTaskAction), new PropertyMetadata(0));

        
        public static readonly DependencyProperty TextToBeCopiedProperty =
            DependencyProperty.Register("TextToBeCopied", typeof(string), typeof(CommonTaskAction), new PropertyMetadata(string.Empty));

        public string PhoneDisplayName
        {
            get { return (string)GetValue(PhoneDisplayNameProperty); }
            set { SetValue(PhoneDisplayNameProperty, value); }
        }

        public string PhoneNO
        {
            get { return (string)GetValue(PhoneNOProperty); }
            set { SetValue(PhoneNOProperty, value); }
        }

        public CommonTaskType TaskType
        {
            get { return (CommonTaskType)GetValue(TaskTypeProperty); }
            set { SetValue(TaskTypeProperty, value); }
        }

        public string TextToBeCopied
        {
            get { return (string)GetValue(TextToBeCopiedProperty); }
            set { SetValue(TextToBeCopiedProperty, value); }
        }

    这时,在 Execute 方法中来完成主要逻辑,添加如下代码:

        public object Execute(object sender, object parameter)
        {
            switch (TaskType)
            {
                case CommonTaskType.CopyText:
                    if (!string.IsNullOrWhiteSpace(TextToBeCopied))
                    {
                        // 复制文本
                        DataPackage dataPackage = new DataPackage
                        {
                            RequestedOperation = DataPackageOperation.Copy,
                        };
                        dataPackage.SetText(TextToBeCopied);
                        Clipboard.SetContent(dataPackage);
                    }
                    break;

                case CommonTaskType.MakePhoneCall:
                    if (!string.IsNullOrWhiteSpace(PhoneNO))
                    {
                        // 打电话
                        Windows.ApplicationModel.Calls.PhoneCallManager.ShowPhoneCallUI(PhoneNO, PhoneDisplayName);
                    }
                    break;
            }

            return true;
        }

     这样,一个自定义 Action 就完成了,它目前只添加了复制文本、打电话的逻辑,你可以根据自己的需求来添加其它的逻辑。
    接下来,我们来看如何使用它。在 MainPage.xaml 中添加如下代码,即可:

<Page ...
      xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
      xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
      xmlns:MyAction="using:CustomActionTest.Actions"

 

  <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid Margin="12">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <TextBlock Style="{ThemeResource TitleTextBlockStyle}" Text="CommonTaskAction 测试" />
            <StackPanel Grid.Row="1" Orientation="Horizontal">
                <TextBox x:Name="txtName"
                         Width="400"
                         Text="这里是测试文本" />
                <Button Content="复制">
                    <Interactivity:Interaction.Behaviors>
                        <Core:EventTriggerBehavior EventName="Tapped">
                            <MyAction:CommonTaskAction TaskType="CopyText" TextToBeCopied="{Binding Text, ElementName=txtName}" />
                        </Core:EventTriggerBehavior>
                    </Interactivity:Interaction.Behaviors>
                </Button>
            </StackPanel>

            <!--  另外一个 MakePhoneCall 就不在这里测试了,可自行测试,用法如下:  -->
            <!--<MyAction:CommonTaskAction TaskType="MakePhoneCall" PhoneNO="13800XXXXXX" PhoneDisplayName="联系人姓名" />-->
        </Grid>
    </Grid>

    注意其中的 TaskType,值表达复制文本, TextToBeCopied,通过绑定,它获取到文本框的值。因而,这个 Action 就可以完成指定的任务。

    理解了本文的思路,现在,你就可以把它改造成适合你的 CommonTaskAction。

    如果你有更好的建议或意见,请留言互相交流。

源码下载

 

参考文章:

Windows通用应用开发手记-Behavior SDK概述

Behaviors SDK

目录
相关文章
|
4月前
|
前端开发 Java Spring
SpringMVC种通过追踪源码查看是哪种类型的视图渲染器(一般流程方法)
这篇文章通过示例代码展示了如何在Spring MVC中编写和注册拦截器,以及如何在拦截器的不同阶段添加业务逻辑。
SpringMVC种通过追踪源码查看是哪种类型的视图渲染器(一般流程方法)
|
4月前
|
容器 C# 开发者
XAML语言大揭秘:WPF标记的魅力所在,让你轻松实现界面与逻辑分离,告别复杂代码!
【8月更文挑战第31天】XAML提供了一种直观且易于维护的界面设计方式,使得开发者可以专注于逻辑和业务代码的编写,而无需关心界面细节。通过数据绑定、布局管理和动画效果等特性,XAML可以实现丰富的界面交互和视觉效果。在实际开发过程中,开发者应根据具体需求选择合适的技术方案,以确保应用程序能够满足用户的需求。希望本文的内容能够帮助您在WPF应用程序开发中更好地利用XAML语言。
51 0
|
6月前
|
数据安全/隐私保护 Python
Python装饰器是高阶函数,用于在不修改代码的情况下扩展或修改函数行为。它们提供可重用性、模块化和无侵入性的功能增强。
【6月更文挑战第20天】Python装饰器是高阶函数,用于在不修改代码的情况下扩展或修改函数行为。它们提供可重用性、模块化和无侵入性的功能增强。例如,`@simple_decorator` 包装`my_function`,在调用前后添加额外操作。装饰器还能接受参数,如`@logged(&quot;INFO&quot;, &quot;msg&quot;)`,允许动态定制功能。
49 6
|
6月前
|
前端开发 JavaScript
详尽分享组件的封装方法【比较高级方法】★★★★★★★
详尽分享组件的封装方法【比较高级方法】★★★★★★★
21 0
|
7月前
|
前端开发 JavaScript 安全
对象属性值的黑魔法:ES8的简化语法让你的代码更简洁
对象属性值的黑魔法:ES8的简化语法让你的代码更简洁
|
JavaScript 前端开发 开发者
带你读《现代Javascript高级教程》二十、JavaScript修饰器:简化代码,增强功能(4)
带你读《现代Javascript高级教程》二十、JavaScript修饰器:简化代码,增强功能(4)
|
前端开发 JavaScript
如何编写神奇的「插件机制」,优化基于 Antd Table 封装表格的混乱代码
最近在一个业务需求中,我通过在 Antd Table 提供的回调函数等机制中编写代码,实现了这些功能: ✨ 每个层级缩进指示线 ✨ 远程懒加载子节点 ✨ 每个层级支持分页
|
XML Java Maven
一个封装好的dialog工具类,减少重复的代码,简洁又方便使用!
一个封装好的dialog工具类,减少重复的代码,简洁又方便使用!
一个封装好的dialog工具类,减少重复的代码,简洁又方便使用!
|
编译器 C++
泛型编程的第一步,掌握模板的特性!
本篇主要是说明「模板」的特性,使用「模板」的特性设计,实际上也就是「泛型」程序设计。
泛型编程的第一步,掌握模板的特性!
|
Java
Java接口概念和语法例子(功能性方法)
比如有三个类。兔子、狗、青蛙这三个类。要定义一个公共游泳方法出来。但是兔子不会这个游泳,那么就不使用这个接口,另外的狗和青蛙会游泳,就会使用这个游泳接口。简单来说,就是谁需要功能接口谁就使用这个功能接口就好了
125 0

热门文章

最新文章