• 【.net 深呼吸】实时获取计算结果


    上次老周介绍了在 UWP 应用中通过 x:Bind 标记来绑定到方法,以实现实时获取计算结果。今天,咱们来耍耍WPF上面的实现方法。

    虽然,WPF 没有 x:Bind 标记(暂时没有,以后不好说),但 WPF 在数据绑定方面也是有很强大的引擎D,毕竟它是 .net 框架一部分。其实,当年在 .net 1.x 的时候,老周就推测微软会推出新的框架的,只是当时还不知道它叫 WPF,为啥呢。因为当时老周发现,Windows 窗体应用相关的类型都放在 System.Windows.Forms 命名空间下,不知道你初学.net 时会不会感到很奇怪,反正老周觉得很怪,为什么不直接放到 System.Windows 命名空间下呢,所以,我就想到,System.Windows 命名空间下将来肯定要放别的东西。

    后来,.net 2.0 SP1,.net 3.0,尤其是 .net 3.5 的时候,这个框架逐步定型,故我一直认为 4.0 是.net 成熟的标志。

    好了,不上历史课了,咱们还是继续上编程课吧。

    在 WPF 中,提供了一种很好玩的绑定模型——DataSourceProvider,当然,它是抽象类,不能直接用的,直接用的话会抽风。它的派生类为我们实现了两种形式的“间接绑定”:XmlDataProvider 可以组件或链接外部的XML文档;ObjectDataProvider可以绑定到某个类型或该类型的实例对象,而且还可以绑定到类型的方法成员上,实例方法或是静态方法皆可。

    要实时获取计算结果,应当使用 ObjectDataProvider 类,如果要绑定实例方法,除了要为 ObjectType 属性设定目标类型的Type外,还要将该类型的实例赋给 ObjectInstance 属性;如果是绑定到静态方法,那就不必要指定 ObjectInstance 属性了。

    然后,通过 MethodName 属性设置要绑定的方法的名字,如果方法有参数,向 MethodParameters 列表添加元素,有几个参数就传几个值,元素的顺序与方法参数的声明一致即可。注意这个方法要有返回值,因为绑定目标要从该方法获取计算结果的。

    下面咱们用一个示例来说明一下。

    首先,得声明一个类,用来进行计算,我就用一个静态方法吧,简单方便。

        public class Demo
        {
            public static double GetMin(double a, double b)
            {
                return Math.Min(a, b);
            }
        }

    这个方法很简单,幼儿园层次的,输入两个数值,返回其中较小的值。 

    然后,重点来了,在 XAML 文档中声明 ObjectDataProvider 实例。

            <Grid.Resources>
                <local:StrAndDoubleConverter x:Key="cvt"/>
                <ObjectDataProvider x:Key="dprd" ObjectType="{x:Type local:Demo}"
                                    MethodName="GetMin">
                    <ObjectDataProvider.MethodParameters>
                        <sys:Double>0</sys:Double>
                        <sys:Double>0</sys:Double>
                    </ObjectDataProvider.MethodParameters>
                </ObjectDataProvider>
            </Grid.Resources>

     StrAndDoubleConverter 是一个自定义的转换器,在 string 和 double 之间转化,这个大家可以无视。

    ObjectType 属性指定的是我们刚刚定义的 Demo 类,MethodName 方法指定刚刚那个静态方法。由于这个方法需要两个输入参数,所以,得向 MethodParameters 中添加两个 double 值,默认全设为 0。

    下面我们在 UI 上放两个 TextBox 控件,用来输入两数值,并且当输入的值改变时,自动把值传递到 ObjectDataProvider 对象的 MethodParameters 列表中。如何实现呢?数据绑定,把 TextBox 的 Text 属性与 MethodParameters 中的元素进行绑定,并且是双向绑定。

                <TextBox Grid.Row="0" Grid.Column="1" Margin="4" Text="{Binding Source={StaticResource dprd},BindsDirectlyToSource=True,Mode=TwoWay,Path=MethodParameters[0],Converter={StaticResource cvt},UpdateSourceTrigger=PropertyChanged}"/>
                <TextBox Grid.Row="1" Grid.Column="1" Margin="4" Text="{Binding Source={StaticResource dprd},BindsDirectlyToSource=True,Mode=TwoWay,Path=MethodParameters[1],Converter={StaticResource cvt},UpdateSourceTrigger=PropertyChanged}"/>

    此处, BindsDirectlyToSource 属性记得要设置为 true,这个是啥意思呢?它的意思就是,这个Binding是直接绑定到 Source 属性所指定的对象,还是原始数据源。在本例这个绑定模型中,原始数据源应为 Demo 类,而中间数据源是 ObjectDataProvider 对象,因此,如果不把 BindsDirectlyToSource 属性设置为true,那么这个 Binding 所相对的是 Demo 类,如果 BindsDirectlyToSource 属性为 true,那么该Binding的相对源就会指向 ObjectDataProvider 对象,这样一来,Path 属性才能找到 MethodParameters 列表中的元素。

    其中,[0] 表示列表中的第一个元素,即传给绑定方法的第一个参数,同理,[1] 就是指向第二个参数。为了能够在 Text 属性更改时更新方法参数,需要设置 UpdateSourceTrigger=PropertyChanged,Mode=TwoWay。

    接着,我们声明一个 TextBlock 元素,同样也是绑定到前面在资源中声明的 ObjectDataProvider 对象上,实时获取计算的结果。

            <TextBlock Grid.Row="1" Margin="5">
                <Run Text="较小的那个数:"/>
                <Run Text="{Binding Source={StaticResource dprd},Mode=OneWay}" Foreground="DarkGreen" FontSize="18"/>
            </TextBlock>

    这里只需要读取结果即可,所以,Mode 为 OneWay 即可。如果计算需要花较长时间,可以设置 IsAsynchronous 属性为 true,这样可以优化 UI 的响应速度。

    好了,示例完成了,咱们来看看运行效果吧。

    而后,老周尝试把方法的返回值改为 void,以 out 和 ref 方式进行计算结果赋值,但绑定后不能获得正确的结果。

    示例源代码下载请点击这里

  • 相关阅读:
    时间戳
    MD5加密、字节与字符串转换、对ToString("X2 ")的理解
    JWT(JSON Web Token)简介
    Entity Framework 通过主键查询提高效率
    C# switch语句与枚举类型
    对象映射库【AutoMapper】所支持场景
    关于EF框架EntityState的几种状态
    EF底层操作注意点、批量操作、更新
    linq:求分组后的每组最大值、最小值、平均值等、Aggregate聚合函数
    Flask——Request(2)
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/7468849.html
Copyright © 2020-2023  润新知