zoukankan      html  css  js  c++  java
  • [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下进行测试,请见谅。
  • 相关阅读:
    Working with WordprocessingML documents (Open XML SDK)
    How to Choose the Best Way to Pass Multiple Models in ASP.NET MVC
    Azure:Manage anonymous read access to containers and blobs
    Convert HTML to PDF with New Plugin
    location.replace() keeps the history under control
    On the nightmare that is JSON Dates. Plus, JSON.NET and ASP.NET Web API
    HTTP Modules versus ASP.NET MVC Action Filters
    解读ASP.NET 5 & MVC6系列(6):Middleware详解
    Content Negotiation in ASP.NET Web API
    Action Results in Web API 2
  • 原文地址:https://www.cnblogs.com/Cajon/p/308221.html
Copyright © 2011-2022 走看看