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也是很优秀的产品,一用到数据绑定就像踩着大便一样……忍不住撰文骂之。

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2011/02/14/1953993.html如需转载请自行联系原作者


xiaotie 集异璧实验室(GEBLAB)

相关文章
|
3月前
|
C#
通过Demo学WPF—数据绑定(一)
通过Demo学WPF—数据绑定(一)
38 1
|
C# 前端开发
WPF - 图形设计器(Diagram Designer)
原文:WPF - 图形设计器(Diagram Designer)   OpenExpressApp计划中包括建模工具,计划是采用MetaEdit+模型来作为元模型,使用codeproject的《WPF Diagram Designer》一系列文章来做为设计器实现参考,本篇介绍一下codeprojcet的这四个文章,推荐给对图形设计器感兴趣的人去看看,通过WPF的模板功能和其他功能可以很方便的设计出图形编辑器。
3572 0
|
3月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
|
3月前
|
安全 C# 数据安全/隐私保护
WPF安全加固全攻略:从数据绑定到网络通信,多维度防范让你的应用固若金汤,抵御各类攻击
【8月更文挑战第31天】安全性是WPF应用程序开发中不可或缺的一部分。本文从技术角度探讨了WPF应用面临的多种安全威胁及防护措施。通过严格验证绑定数据、限制资源加载来源、实施基于角色的权限管理和使用加密技术保障网络通信安全,可有效提升应用安全性,增强用户信任。例如,使用HTML编码防止XSS攻击、检查资源签名确保其可信度、定义安全策略限制文件访问权限,以及采用HTTPS和加密算法保护数据传输。这些措施有助于全面保障WPF应用的安全性。
51 0
|
3月前
|
数据处理 开发者 C#
WPF数据绑定实战:从零开始,带你玩转数据与界面同步,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据绑定是核心技能之一,它能实现界面元素与数据源的同步更新。本文详细介绍了WPF数据绑定的概念与实现方法,包括属性绑定、元素绑定及路径绑定等技术,并通过示例代码展示了如何创建数据绑定。通过数据绑定,开发者不仅能简化代码、提高可维护性,还能提升用户体验。无论初学者还是有经验的开发者,都能从中受益,更好地掌握WPF数据绑定技巧。
76 0
|
3月前
|
存储 开发框架 .NET
通过Demo学WPF—数据绑定(二)
通过Demo学WPF—数据绑定(二)
39 1
|
3月前
|
C#
WPF/C#:数据绑定到方法
WPF/C#:数据绑定到方法
41 0
|
C# 存储
【值转换器】 WPF中Image数据绑定Icon对象
原文:【值转换器】 WPF中Image数据绑定Icon对象        这是原来的代码:                这里的MenuIcon是string类型,MenuIcon = "/Image/Tux.ico"。
903 0
|
C#
wpf Content数据绑定StringFormat起作用的原理和解决
原文:wpf Content数据绑定StringFormat起作用的原理和解决 03/29/2016 15:05:30 TextBox按照预期的,显示了完整的英文星期,但是Label的格式没有任何改变。
1576 0
|
C# 数据安全/隐私保护 索引
WPF入门:数据绑定
原文:WPF入门:数据绑定 上一篇我们将XAML大概做了个了解 ,这篇将继续学习WPF数据绑定的相关内容 数据源与控件的Binding Binding作为数据传送UI的通道,通过INotityPropertyChanged接口的PropertyChanged事件通知Binding数据属性...
1130 0