• [转]WPF实例秀——不用属性也Binding(XAML篇)


    实际编程中,因为我们较多地使用到Binding类的Source与Path,所以可能会有一个思维定式,那就是:有可能作为数据源的类一定要准备好一些属性,这些属性将作为Binding的Path。

    如果本着这个思想去设计有可能作为数据源的类,那么会有两个问题出现:

    1. 这个类的哪些属性有可能作为数据源的Path?是都需要激发NotifyPropertyChanged事件,还是用到了再添加?这很有可能让这个类迟迟不能封闭。

    2. 需要用属性把一些方法包装起来,用来暴露给Binding,造成冗余和语义上的不美观。

    其实,WPF类库里有一个名为ObjectDataProvider的类就是专门为了解决这个矛盾的——有了这个类,你在设计自己的类的时候就不必总想着把它设计成数据源的事儿了,该怎么抽象就怎么抽象、该怎么封装就怎么封装。

    你可能会问:“如果这个类已经封闭了(不再改动)而我又需要拿它当数据源了,碰巧所需要的数据是它某个方法的返回值,没有对应属性,怎么办?”OK,这就是ObjectDataProvider的用武之地了——使用它,可以在你这个类的实例外面加上一层“包装”(或者说是加个壳儿),使它变成一个标准的Binding数据源。如果没记错的话,这应该是著名的“适配器模式”

     

    下面,我们用一段简单的代码来学习如何使用ObjectDataProvider。

     

    这个例子简单到不能再简单——三个TextBox,在前两个里输入合适的数字,在第三个里会显示它们的和。按照UI与逻辑分开的原则,计算加法的功能应该由某个类来实现。

     

    后台负责计算的类是这样:

    1.     public class Calculator
    2.     {
    3.         public int Add(int arg1, int arg2)
    4.         {
    5.             return arg1 + arg2;
    6.         }
    7.         public string Add(string arg1, string arg2)
    8.         {
    9.             int x = 0;
    10.             int y = 0;
    11.             if (int.TryParse(arg1, out x) && int.TryParse(arg2, out y))
    12.             {
    13.                 return this.Add(x, y).ToString();
    14.             }
    15.             else
    16.             {
    17.                 return "Input Error!";
    18.             }
    19.         }
    20.     }

    大家看到了,设计这个类的时候,涉及到加法运算的逻辑时,任何一个程序员都会很自然地采用一个方法来实现,而不会为了把它做成一个Binding的数据源专门把这些方法封装进属性里——这样就破坏了面向对象的抽象。

     

    然后,让我们看看如何使用ObjectDataProvider来包装这个类。

     

    1. <Window x:Class="WpfApplicationAdd.Window1"
    2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4.         xmlns:local="clr-namespace:WpfApplicationAdd"
    5.         xmlns:system="clr-namespace:System;assembly=mscorlib"
    6.     Title="Add" Height="136" Width="230" Background="SteelBlue">
    7.     <Window.Resources>
    8.         <ObjectDataProvider x:Key="odp" ObjectType="{x:Type local:Calculator}" MethodName="Add">
    9.             <ObjectDataProvider.MethodParameters>
    10.                 <system:String>0</system:String>
    11.                 <system:String>0</system:String>
    12.             </ObjectDataProvider.MethodParameters>
    13.         </ObjectDataProvider>
    14.     </Window.Resources>
    15.     <StackPanel>
    16.         <TextBox x:Name="textBox1" Margin="5" Text="{Binding Source={StaticResource odp}, Path=MethodParameters[0], BindsDirectlyToSource=true, UpdateSourceTrigger=PropertyChanged}" />
    17.         <TextBox x:Name="textBox2" Margin="5" Text="{Binding Source={StaticResource odp}, Path=MethodParameters[1], BindsDirectlyToSource=true, UpdateSourceTrigger=PropertyChanged}"/>
    18.         <TextBox x:Name="textBox3" Margin="5" Text="{Binding Source={StaticResource odp}, Mode=OneWay}"/>
    19.     </StackPanel>
    20. </Window>

    运行起来之后,你就能看到这样的结果了:

     

    网友建议:我建议在实现一个IValueConverter类,作用将string转换为double类型,那么就不需要在Calculator类中实现string为参数的重载方法(因为Calculator类的设计者并不想让string加string变成加法操作,有可能他需要concat操作)。
    假设实现类为DoubleValueConverter,在资源中加入<loc:DoubleValueConverter x:Key="dc" />,然后
    只需要在xaml中更改为:<TextBox x:Name="textBox1" Margin="5" Text="{Binding Source={StaticResource odp}, Path=MethodParameters[0], BindsDirectlyToSource=true, UpdateSourceTrigger=PropertyChanged,Converter={StaticResource dc}}" />
    这样就更优雅些。

     

    文章来源:http://blog.csdn.net/fantasiax/article/details/3525985

  • 相关阅读:
    浅谈P2P
    一串字符的解密
    下载地址解密
    初探DirectX
    本文介绍在VC 6.0中编译和使用OpenSSL的过程
    鱼钩绑线视频
    PKCS cer 证书
    02、创建顶点缓冲
    [原]SSL 开发简述(Delphi)
    [转]Delphi和C++数据类型对照表
  • 原文地址:https://www.cnblogs.com/luohengstudy/p/3096555.html
Copyright © 2020-2023  润新知