[WPF]WPF中如何实现数据与表示分离。(一) —— XAML

软件复用一直是现代软件工程所追求的目标。提高软件复用性的一个关键点就是“数据表示分离”(表示:数据的展示方式)。
这个系列文章将以“如何分离数据与表示”做为主线,能够概要的介绍一些在WPF中引入的新的编程技术和概念。

在这个系列里面,我们将使用Kevin Moore的ColorPicker作为一个例子,通过逐渐深入的引入WPF中的新概念,来演示这些新概念对我们的开发有什么好处。

首先,让我们来介绍一下ColorPicker可以干什么?
        ColorPicker运行效果如下图:
        ColorPicker1.GIF

通过拖动左边的Slider可以动态的改变右面预览窗口的背景颜色。

本系列文章将逐步的引入WPF中的概念,主要包括下面的几个步骤:
1. XAML
2. Binding
4. Convert.
3. Styling

我希望在每一阶段我们都尽量的将焦点集中在一个问题上,同时能够对这个问题相关的因素进行简单的介绍,以达到通过这个系列能够让大家对WPF有一个概括的了解。

OK, Let's GO...


在WPF中,微软引入了XAML(可扩展应用程序标记语言)的概念。其实XAML本不是一个新事物,在理论界已经经过多年的研究,应该说已经形成了一个相对成熟的体系。
简单来说,XAML就是一个应用程序界面的描述语言,(呵呵,这个描述可能并不准确,但是可能会更好理解一些)。就像我们以前编写VB程序或Delphi程序,会将界面按照一定的描述方式保存起来一样。
但是,XAML是基于XML的,因此,它与生俱来的具有XML的优势——跨平台,可扩展。

我们先来看一下如何用XAML来描述一个程序的界面:

None.gif < Window  x:Class ="Freezed.Window1"
None.gif    xmlns
="http://schemas.microsoft.com/winfx/avalon/2005"
None.gif    xmlns:x
="http://schemas.microsoft.com/winfx/xaml/2005"
None.gif    Title
="Color Picker"
None.gif    Height
="130"  Width ="300"
None.gif    
>
None.gif    
< Grid >
None.gif      <RowDefinition/>
None.gif      
<RowDefinition/>
None.gif      
<RowDefinition/>
None.gif      <ColumnDefinition Width="40"/>
None.gif      
<ColumnDefinition Width="150"/>
None.gif      
<ColumnDefinition Width="12"/>
None.gif      
<ColumnDefinition/>
None.gif      
None.gif      
< TextBlock  Grid.Column ="0"  Grid.Row ="0" > Red: </ TextBlock >
None.gif      <Slider Name="greenSlider" Grid.Column="1" Grid.Row="1"
None.gif              Minimum
="0" Maximum="255"              
None.gif              ValueChanged
="OnGreenSliderChanged"/>

None.gif       < TextBlock  Name ="redValue"  Grid.Column ="2"  Grid.Row ="0" />
None.gif      
None.gif      
< TextBlock  Grid.Column ="0"  Grid.Row ="1" > Green: </ TextBlock >
None.gif      
< Slider  Name ="greenSlider"  Grid.Column ="1"  Grid.Row ="1"
None.gif              Minimum
="0"  Maximum ="255"               
None.gif              ValueChanged
="OnGreenSliderChanged" />
None.gif      
< TextBlock  Name ="greenValue"  Grid.Column ="2"  Grid.Row ="1" />
None.gif      
None.gif      
< TextBlock  Grid.Column ="0"  Grid.Row ="2" > Blue: </ TextBlock >
None.gif      
< Slider  Name ="blueSlider"  Grid.Column ="1"  Grid.Row ="2"
None.gif              Minimum
="0"  Maximum ="255"               
None.gif              ValueChanged
="OnBlueSliderChanged" />
None.gif      
< TextBlock  Name ="blueValue"  Grid.Column ="2"  Grid.Row ="2" />
None.gif      
None.gif      
< Border  Grid.Column ="3"  Grid.Row ="0"  Grid.RowSpan ="3"  Margin ="5, 5, 5, 5" >
None.gif        
< Border  Name ="Preview"  BorderThickness ="1"  CornerRadius ="5"  BorderBrush ="Gray"  Background ="Black" />
None.gif      
</ Border >
None.gif    
</ Grid >
None.gif
</ Window >

1. 对象
一般情况下,XML文件中的节点可以对应到一个对象或一个属性上。
各个节点之间的层次结构描述了节点之间的从属关系,例如:Window节点是这个XML的根节点,这个节点描述了一个Window对象,运行时,我们可以看到会弹出一个标准的Windows窗口出来。
这个Window对象中包含一个Grid对象,这个Grid中包含3个Slider,6个TextBlock和一个Border对象。加黄的部分是一段比较特殊的部分,后面我会专门写文章来讨论。

2. 属性
XAML中节点的属性对应到这个节点所描述对象的属性上。例如:上面的XAML中红色的部分描述了一个Slider对象,这个对象有3个属性:Minimum,Maximum,Name。Grid.Column和Grid.Row两个属性是 附加属性
如果一个XAML中的节点包含属性Name,编译器将会在代码中生成一个同名的变量引用到这个对象上。这一点,是由IDE的CodeGenerical来实现的。相关的内容,如果以后有时间,我会专门写文章来讨论IDE的CodeGenerator。

3. 事件
XAML中的事件使用和属性相同的语法来描述。例如:Slider对象的ValueChanged是一个事件。它将映射到Code中的一个方法上。

Ok, 我们现在来看一下代码怎样编写:
 1 None.gif using  System;
 2 None.gif using  System.Windows;
 3 None.gif using  System.Windows.Controls;
 4 None.gif using  System.Windows.Data;
 5 None.gif using  System.Windows.Documents;
 6 None.gif using  System.Windows.Media;
 7 None.gif using  System.Windows.Shapes;
 8 None.gif
 9 None.gif namespace  Freezed
10 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
11InBlock.gif    public partial class Window1 : Window
12ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
13InBlock.gif        public Window1()
14ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
15InBlock.gif            InitializeComponent();
16ExpandedSubBlockEnd.gif        }

17InBlock.gif
18InBlock.gif        Color _value = Colors.Black;
19InBlock.gif
20InBlock.gif        public void OnRedSliderChanged(Object sender, RoutedPropertyChangedEventArgs<double> e)
21ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
22InBlock.gif            this._value = Color.FromArgb(_value.A, Convert.ToByte(e.NewValue), _value.G, _value.B);
23InBlock.gif            this.OnValueChanged();
24ExpandedSubBlockEnd.gif        }

25InBlock.gif        public void OnGreenSliderChanged(Object sender, RoutedPropertyChangedEventArgs<double> e)
26ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
27InBlock.gif            this._value = Color.FromArgb(_value.A, _value.R, Convert.ToByte(e.NewValue), _value.B);
28InBlock.gif            this.OnValueChanged();
29ExpandedSubBlockEnd.gif        }

30InBlock.gif        public void OnBlueSliderChanged(Object sender, RoutedPropertyChangedEventArgs<double> e)
31ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
32InBlock.gif            this._value = Color.FromArgb(_value.A, _value.R, _value.G, Convert.ToByte(e.NewValue));
33InBlock.gif            this.OnValueChanged();
34ExpandedSubBlockEnd.gif        }

35InBlock.gif
36InBlock.gif        private void OnValueChanged()
37ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
38InBlock.gif            this.Preview.Background = new SolidColorBrush(this._value);
39InBlock.gif            this.redValue.Text = this._value.R.ToString();
40InBlock.gif            this.greenValue.Text = this._value.G.ToString();
41InBlock.gif            this.blueValue.Text = this._value.B.ToString();
42ExpandedSubBlockEnd.gif        }

43ExpandedSubBlockEnd.gif    }

44ExpandedBlockEnd.gif}
代码很简单,无非就是实现了XAML中声明调用的方法,然后同步几个对象的属性。

写到这里,发现这一章好像和“数据与表示分离”主题没有太多的关系。先作为预备知识,大家了解一下吧。因为后面的文章都会基于XAML来讨论。

XAML是WPF的核心概念之一。但是,很多人看到这里都会有这样的疑问:为什么要XAML?
微软引入XAML的一个主要的原因就是为了将界面和业务逻辑进行分离。在不远的将来,一个软件公司必须包含两类技术人才,一类是开发人员,而另一类就是设计人员。开发人员负责实现具体的业务逻辑,而设计人员仅仅进行UI的设计。他们的主要机能就是能够很好的操控XAML(与现在的WEB开发有点类似)。同时,微软正在开发新的设计器来实现可视化UI设计(花哨的就象Photoshop和CorelDraw)。

下面引用一篇老外的Blog供大家参考: If xaml is so easy, why is code so hard? 

下一篇Blog中,我们将讨论如何使用Binding实现数据与表示的分离。

本文的例子: ColorPicker1.rar
注意:本文相关的例子都在WinFX 11月CTP下测试通过,因为目前环境限制,没能再12月CTP下进行测试,请见谅。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值