zoukankan      html  css  js  c++  java
  • WPF/Silverlight的数据绑定设计的真糟糕

    WPF/Silverlight的数据绑定体系设计的真糟糕,几乎每用一次就要在心中骂一次,不知道是哪个家伙设计的,就像Asp.Net中的ViewState一样,拙劣得很:

    (1)很难用,一些常见的简单场合使用起来很麻烦;

    (2)想整个搞清楚很杀脑细胞,不是循序渐进的过程;

    (3)不整个搞清楚就用不好,或者用的很别扭。

    总之,就是一个这样的怪胎——简单的场景下使用很麻烦(增加了很多工作量),复杂的场景下使用很绕弯(也减少了不少工作量)。抄起原子弹当锤子用。一般的开发,哪有那么多复杂的场景?大部分情况都是简单的场景。我们需要的是一个在简单的场景下使用简单,在复杂的场景下使用略微复杂的设计,就像《.Net设计规范》中标榜的那样应该是一个倾斜的山坡(下图左),而不是像屋檐(下图右)。

    image

    下面开骂,参考对象是Flex哥哥:

    (1)最常用的场景是把A或者A的属性F绑定到B的属性Source上;

    WPF/SL下:

    Source="{Binding ElementName=A, Path=F}"

    Flex下:

    Source="{A.F}"

    这是最最常用的场景,WPF/SL罗哩罗嗦不说,还是弱类型性质的绑定,很容易写错,写错了编译器也不报错。

    (2)再一个常见的场景是进行简单的判断或者简单的类型转换,这种应用非常常见。

    WPF/SL下:

    要用IValueConverter,blablabla … 要写一大堆代码。我还没写过IValueConverter,前面的场景还可以忍受,这种情况就忍无可忍了,直接放弃使用绑定了。下面是从网上找的例子:

    [ValueConversion(typeof(DateTime), typeof(String))]
    public class DateConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DateTime date = (DateTime)value;
            return "now is "+date.ToString();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string strValue = value.ToString();
            DateTime resultDateTime;
            if (DateTime.TryParse(strValue, out resultDateTime))
            {
                return resultDateTime;
            }
            return value;
        }
    }

    这不是给自己找虐吗?

    Flex下:

    function convert(obj:Object):String

    {

       …

    }

    Source="{convert(A.F)}"

    也可以直接在大括号里面写语句,如:

    toValue="{controlsBar.y - 45}"

    下面看一段Flex代码:

    <mx:AnimateProperty target="{controlsBar}"
                        property="y" fromValue="{controlsBar.y}"
                        toValue="{controlsBar.y - 45}">
    </mx:AnimateProperty>

    这代码要用WPF/SL写,不知道会多别扭。.Net空有lambda表达式,又不能用于数据绑定的内部,真是悲哀(可以绕道用,但十分别扭)。

    (3)再一个常见的场景就是自定义绑定源

    WPF/SL下,还是网上找的代码:

    public class MenuButtonModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private bool? _hasFocus;
        public bool? HasFocus
        {
            get { return _hasFocus; }
            set
            {
                _hasFocus = value;
                NotifyPropertyChanged("HasFocus");
            }
        }

        private string _iconPath;
        public string IconPath
        {
            get { return _iconPath; }
            set
            {
                _iconPath = value;
                NotifyPropertyChanged("IconPath");
            }
        }
    }


    对应Flex的实现:

    [Bindable]
    public class MenuButtonModel : IEventDispatcher
    {
        public var hasFocus:Boolean;
        public var iconPath:String;
    }


    加一个Bindable就把里面的字段啊,属性啊,全设为改变后发出一个事件。如果只想对特定字段或属性进行绑定,则是:

    public class MenuButtonModel : IEventDispatcher
    {
        [Bindable]
        public var hasFocus:Boolean;
        ...

        [Bindable]
        public function set iconPath():String
        {
            ...
        }
    }

    相比较而言,Flex的语法简介太多了。.Net空有“特性”这玩意,在睡大觉。

    以上三种是最最常见的绑定场景,WPF/SL那语法就是找虐用的。相比较WPF/SL,Flex的绑定语法使用简单,又是强类型,学习3分钟就可以上手开发了。手中只有一本WPF的书《WPF核心技术》,整整用了一章讲数据绑定(第6章),连XPath绑定也单独作为一个小节来讲,晕。如果WPF/SL实现了Flex的绑定语法,只需要提供一个扩展方法就搞定了的事情,搞得这么麻烦。

    当然,WPF/SL的绑定机制也有优秀的一面,就是当应用场景比较复杂时,会比Flex的数据绑定要简单一点。比如说双向绑定(这玩意用的很少吧),双向绑定在Flex下其实也不麻烦,不需要学新东西即可实现:

    x={B.y}

    y={A.x}

    绑定两次即可,关键是语法比较简单,写起来并不费事,且绑定逻辑一目了然。WPF/SL写起来虽然简单一点,但有副作用。不知道啥时候就被别人给代表了,而不是自己主动去声明让别人来代表自己。

    再比如说,上面的第三种绑定场景,Flex下只能发出PropertyChanged事件,WPF/SL下可以自定义事件类型,触发时也可以选择触发,这种情况,Flex下就要依靠OO技法来实现了。至于Tree绑定,DataGrid的绑定,WPF/SL和Flex是半斤八两。还有些更复杂的场景,没遇见过,就不做评价了。

    ====

    这玩意不知道是哪个鼠标流大哥设计的,过渡设计的经典案例,真应该拉出去tjjtds。写代码写得实在不爽,本来C#是很优雅的东西,WPF也是很优秀的产品,一用到数据绑定就像踩着大便一样……忍不住撰文骂之。

  • 相关阅读:
    EBS 获取用户密码
    Using Create directory & UTL_FILE in Oracle
    Loops with PL/SQL
    Create trigger
    Oracle DB解锁和 rerun FA depreciation
    oracle中数组的运用
    FNDLOAD使用大全
    不安装Oracle客户端,透过PL/SQL Developer连接Server DB
    R12组织屏蔽
    Oracle DB Link创建
  • 原文地址:https://www.cnblogs.com/xiaotie/p/1953993.html
Copyright © 2011-2022 走看看