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


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

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

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

    通过拖动左边的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来描述一个程序的界面:

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

          <TextBlock Name="redValue" Grid.Column="2" Grid.Row="0"/>
          
          
    <TextBlock Grid.Column="0" Grid.Row="1">Green:</TextBlock>
          
    <Slider Name="greenSlider" Grid.Column="1" Grid.Row="1"
                  Minimum
    ="0" Maximum="255"              
                  ValueChanged
    ="OnGreenSliderChanged"/>
          
    <TextBlock Name="greenValue" Grid.Column="2" Grid.Row="1"/>
          
          
    <TextBlock Grid.Column="0" Grid.Row="2">Blue:</TextBlock>
          
    <Slider Name="blueSlider" Grid.Column="1" Grid.Row="2"
                  Minimum
    ="0" Maximum="255"              
                  ValueChanged
    ="OnBlueSliderChanged"/>
          
    <TextBlock Name="blueValue" Grid.Column="2" Grid.Row="2"/>
          
          
    <Border Grid.Column="3" Grid.Row="0" Grid.RowSpan="3" Margin="5, 5, 5, 5">
            
    <Border Name="Preview" BorderThickness="1" CornerRadius="5" BorderBrush="Gray" Background="Black"/>
          
    </Border>
        
    </Grid>
    </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, 我们现在来看一下代码怎样编写:
     1using System;
     2using System.Windows;
     3using System.Windows.Controls;
     4using System.Windows.Data;
     5using System.Windows.Documents;
     6using System.Windows.Media;
     7using System.Windows.Shapes;
     8
     9namespace Freezed
    10{
    11    public partial class Window1 : Window
    12    {
    13        public Window1()
    14        {
    15            InitializeComponent();
    16        }

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

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

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

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

    43    }

    44}
    代码很简单,无非就是实现了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下进行测试,请见谅。
  • 相关阅读:
    连接池的配置与维护
    对面向对象的理解
    ActiveMQ重试机制
    activemq持久化的几种方式详解
    zookeeper写数据流程
    G1垃圾回收器
    REDIS哨兵模式和集群模式
    REDIS复制
    REDIS参数配置和运行状态
    slow-log 和bin-log相关参数介绍
  • 原文地址:https://www.cnblogs.com/Cajon/p/308221.html
Copyright © 2020-2023  润新知