红俊's profile蝈蝈俊的共享空间PhotosBlogListsMore Tools Help

Blog


    November 26

    REST 软件架构风格学习笔记

    REST 是 Representational State Transfer 的简称,是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。

    REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。

    这些条件和原则包括:

    网络上的所有事物都被抽象为资源(resource);

    资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。

     

    每个资源对应一个唯一的资源标识符(resource identifier);

    每个资源都使用 URI (Universal Resource Identifier) 得到一个惟一的地址。所有资源都共享统一的界面,以便在客户端和服务器之间传输状态。

    对事物使用一致的命名规则(naming scheme)最主要的好处就是你不需要提出自己的规则——而是依靠某个已被定义,在全球范围内,能被绝大多数人所理解的规则。比如,如果你的应用中包含一个对顾客的抽象,那么我可以相当肯定,用户会希望将一个指向某个顾客的链接,能通过电子邮件发送到同事那里,或者加入到浏览器的书签中,甚至写到纸上。更透彻地讲:如果在一个类似于Amazon.com的在线商城中,没有用唯一的ID(一个URI)标识它的每一件商品,可想而知这将是多么可怕的业务决策。

    当面对这个原则时,许多人惊讶于这是否意味着需要直接向外界暴露数据库记录(或者数据库记录ID)——自从多年以来面向对象的实践告诫我们,要将持久化的信息作为实现细节隐藏起来之后,哪怕是刚有点想法都常会使人惊恐。但是这条原则与隐藏实现细节两者之间并没有任何冲突:通常,值得被URI标识的事物——资源——要比数据库记录抽象的多。例如,一个定单资源可以由定单项、地址以及许多其它方面(可能不希望作为单独标识的资源暴露出来)组成。标识所有值得标识的事物,领会这个观念可以进一步引导你创造出在传统的应用程序设计中不常见的资源:一个流程或者流程步骤、一次销售、一次谈判、一份报价请求——这都是应该被标识的事物的示例。同样,这也会导致创建比非RESTful设计更多的持久化实体。

    下面是一些你可能想到的URI的例子:

    http://example.com/customers/1234
    http://example.com/orders/2007/10/776654
    http://example.com/products/4554
    http://example.com/processes/salary-increase-234

     

    通过通用的连接器接口(generic connector interface)对资源进行操作;

    对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。

    REST软件架构遵循了CRUD原则,该原则告诉我们对于资源(包括网络资源)只需要四种行为:创建(Create)、获取(Read)、更新(Update)和销毁(DELETE)就可以完成对其操作和处理了。其实世界万物都是遵循这一规律:生、变、见、灭。所以计算机世界也不例外。这个原则是源自于我们对于数据库表的数据操作:insert(生)、select(见)、update(变)和delete(灭),所以有时候CRUD也写作为RUDI,其中的I就是insert。这四个操作是一种原子操作,即一种无法再分的操作,通过它们可以构造复杂的操作过程,正如数学上四则运算是数字的最基本的运算一样。

     

    对资源的各种操作不会改变资源标识符;

    资源一旦产生,就不应该随便更改标识符,一些网站经常变化自己帖子的地址,这显然是反面的做法。

     

    所有的操作都是无状态的(stateless)。

    客户端和服务器之间的交互在请求之间是无状态的。

    从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。

    RESTful 应用程序是无状态的。这意味着在 REST 应用程序中,服务器上没有存储任何会话状态。满足请求所需要的所有信息都携带在请求消息本身之中。因此在服务显式地允许的情况下,客户端可以缓存资源的表示形式,从而显著改进应用程序的性能。

    REST对于连接的无状态性实际上要求每次经过无状态的连接协议传送的信息必须包含应用中所有的状态信息。

     

    参考资料:

    REST - 维基百科,自由的百科全书
    http://zh.wikipedia.org/wiki/REST
    REST
    http://www.hudong.com/wiki/rest

    理解REST软件架构
    http://www.infoq.com/cn/articles/rest-architecure

    深入浅出REST
    http://www.infoq.com/cn/articles/rest-introduction

    Ajax/REST 架构风格对于融入式 Web 应用程序的优点
    http://www.ibm.com/developerworks/cn/web/wa-ajaxarch/

    Web Service实践之REST vs RPC
    http://www.cnblogs.com/mindsbook/archive/2009/11/17/web_service_RESTvsRPC.html

    REST 与 Web 开发
    http://www.ibm.com/developerworks/cn/web/lp/restandweb/

    基于REST架构的Web Service设计
    http://www.williamlong.info/archives/1728.html

    November 25

    Silverlight学习笔记--绘制与着色(下)

    下面是刷子的一些内容:

    纯色刷子(SolidColorBrush)

    Silverlight中使用纯色刷子可以有多种方式如下,

    <object property="predefinedColor"/>
    - or -
    <object property="#rgb"/>
    - or -
    <object property="#argb"/>
    - or -
    <object property="#rrggbb"/>
    - or -
    <object property="#aarrggbb"/>
    - or -
    <object property="sc# scA,scR,scG,scB"/>

    分别代表的意思如下:

    predefinedColor   Colors 类预定义的颜色之一。

    rgb     一个三位数的十六进制数字。第一位数指定颜色的 R 值,第二位数指定 G 值,第三位数指定 B 值。例如 00F。

    argb   一个四位数的十六进制数字。第一位数指定颜色的 A 值,第二位数指定其 R 值,下一位数指定 G 值,最后一位数指定其 B 值。例如 F00F。

    rrggbb   一个六位数的十六进制数字。前两位数指定颜色的 R 值,下两位数指定其 G 值,最后两位数指定其 B 值。例如 0000FF。

    aarrggbb   一个八位数的十六进制数字。前两位数指定颜色的 A 值,下两位数指定其 R 值,接下来的两位指定其 G 值,最后两位数指定其 B 值。例如 FF0000FF。

    scA   System.Single   颜色的 ScA 值。

    scR   System.Single   颜色的 ScR 值。

    scG   System.Single   颜色的 ScG 值。

    scB   System.Single   颜色的 ScB 值。

    演示代码如下:

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	x:Class="SilverlightStudy.MainPage"
    	Width="640" Height="480">
    <Canvas>
      <Ellipse Height="90" Width="90" Canvas.Left="10" Canvas.Top="10" Fill="black"/>
    
      <Ellipse Height="90" Width="90" Canvas.Left="110" Canvas.Top="10" Fill="#000000"/>
    
      <Ellipse Height="90" Width="90" Canvas.Left="210" Canvas.Top="10" Fill="#000" />
    
      <Ellipse Height="90" Width="90" Canvas.Left="310" Canvas.Top="10" Fill="sc# 0.0 0.0 1.0" />
    
      <Ellipse Height="90" Width="90" Canvas.Left="10" Canvas.Top="110" Fill="#ff000000"/>
    
      <Ellipse Height="90" Width="90" Canvas.Left="110" Canvas.Top="110">
        <Ellipse.Fill>
    	  <SolidColorBrush Color="Black"/>
        </Ellipse.Fill>
      </Ellipse>
     
      <Ellipse Height="90" Width="90" Canvas.Left="210" Canvas.Top="110" Fill="#f000"/>
     
      </Canvas>
    </UserControl>

    演示效果如下:

    image

    需要注明的是 WPF 中支持的另外一种颜色定义方式,如下,Silverlight 是不支持的:

    <!-- This rectangle fill uses the sRGB color profile and values to create a complete opaque blue. -->
      <Rectangle Width="50" Height="50"  Margin="10">
        <Rectangle.Fill>
          <SolidColorBrush Color="ContextColor 
    	   file://C:/WINDOWS/system32/spool/drivers/color/sRGB%20Color%20Space%20Profile.icm
    	   1.0,0.0,0.0,1.0"/>
        </Rectangle.Fill>
      </Rectangle>

    线性渐变刷子(LinearGradientBrush)

    默认的线性渐变是沿对角方向进行的。默认情况下,线性渐变的 StartPoint 是被绘制区域的左上角 (0,0),其 EndPoint 是被绘制区域的右下角 (1,1)。所得渐变的颜色是沿着对角方向路径插入的。如下图显示了对角方向的渐变。图中添加了一条线,用于突出显示渐变从起点到终点的插值路径。

    对角线方向线性渐变的渐变轴

     

    具有突出显示的渐变停止点的对角线性渐变,如下图:

    线性渐变中的渐变停止点

    演示代码

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	x:Class="SilverlightStudy.MainPage"
    	Width="640" Height="480">
    <Canvas>
    
      <!-- 水平渐变 //-->
      <Rectangle Width="140" Height="70" Canvas.Left="155" Canvas.Top="10">
        <Rectangle.Fill>
          <LinearGradientBrush  StartPoint="0,0" EndPoint="1,0">
            <GradientStop Color="Red" Offset="0.0" />
            <GradientStop Color="LimeGreen" Offset="1.0" />
          </LinearGradientBrush>
        </Rectangle.Fill>
      </Rectangle>
      <!-- 垂直渐变 //-->
     <Rectangle Width="140" Height="70" Canvas.Left="300" Canvas.Top="10">
        <Rectangle.Fill>
          <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="Blue" Offset="0.0" />
            <GradientStop Color="LimeGreen" Offset="1.0" />
          </LinearGradientBrush>
        </Rectangle.Fill>
      </Rectangle>
      
      <!-- 具有突出显示的渐变停止点的对角线性渐变 //-->
     <Rectangle Width="140" Height="70" Canvas.Left="450" Canvas.Top="10">
        <Rectangle.Fill>
          <LinearGradientBrush>
            <GradientStop Color="Yellow" Offset="0.0" />
            <GradientStop Color="Red" Offset="0.25" />
            <GradientStop Color="Blue" Offset="0.75" />
            <GradientStop Color="LimeGreen" Offset="1.0" />
          </LinearGradientBrush>
        </Rectangle.Fill>
      </Rectangle>
      
      </Canvas>
    </UserControl>

    执行效果

    image

    其中的一些属性说明

    Offset 渐变停止点在渐变向量中的位置。值 0.0 指定停止点位于渐变向量的开始处;而值 1.0 指定停止点位于渐变向量的末尾处。如果没有设置这个值,则默认是0.0。

     

    径向渐变刷子(RadialGradientBrush)

    焦点定义渐变的开始,而圆定义渐变的终点。

    范例代码:

    <!-- This rectangle is painted with a diagonal linear gradient. -->
    <Rectangle Width="200" Height="100">
      <Rectangle.Fill>
        <RadialGradientBrush 
          GradientOrigin="0.5,0.5" Center="0.5,0.5" 
          RadiusX="0.5" RadiusY="0.5">
          <GradientStop Color="Yellow" Offset="0" />
          <GradientStop Color="Red" Offset="0.25" />
          <GradientStop Color="Blue" Offset="0.75" />
          <GradientStop Color="LimeGreen" Offset="1" />
        </RadialGradientBrush>
      </Rectangle.Fill>
    </Rectangle>
    效果图如下:

    径向渐变中的渐变停止点

    其中一些属性的意思如下

    GradientOrigin : 定义渐变开始的二维焦点的位置。(下面演示图中的红点),可以在径向渐变最外面的圆外面,渐变的二维焦点的位置。默认值为 (0.5, 0.5)。

    Center :径向渐变最外面的圆的圆心,渐变圆的默认中心点位置是 (0.5, 0.5)。

    RadiusX:径向渐变最外面的圆的水平半径,默认值为 0.5。

    RadiusY:径向渐变最外面的圆的垂直半径,默认值为 0.5。

    注意,上面坐标系是相对于边界框的:0 表示边界框的 0%,1 表示边界框的 100%。可以通过将 MappingMode 属性设置为值 Absolute 来更改此坐标系。绝对坐标系不是相对于边界框的。值直接在本地坐标系中解释。

    我们可以看下面的例子来理解具有不同 GradientOrigin、Center、RadiusX 和 RadiusY 设置的 RadialGradientBrush。

    RadialGradientBrush 设置

     

    图像绘制刷子(ImageBrush)

    实例代码:

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	x:Class="SilverlightStudy.MainPage"
    	Width="640" Height="480">
    <Canvas>
      <Rectangle Height="180" Width="90" Canvas.Left="110" Canvas.Top="36"
          Stroke="Bisque" StrokeThickness="1">
        <Rectangle.Fill>
          <ImageBrush ImageSource="7116_2004321149418456.jpg" Stretch="Uniform"/>
        </Rectangle.Fill>
      </Rectangle>
      </Canvas>
    </UserControl>

    效果如下:这里的原始图片是一个380*486 的大尺寸图片。

    image

     

    其中的 Stretch 属性用于控制图像的拉伸、对齐和平铺方式。默认值为 Fill。

    Stretch 属性可以设置为以下几种值:

    • None:内容不拉伸以填充图块。
    • Uniform:内容进行缩放,以适合图块尺寸。但保留该内容的纵横比。
    • UniformToFill:对内容进行缩放,从而可以完全填充输出区域,但保持其原始纵横比。
    • Fill:内容进行缩放,以适合图块。由于内容的高度和宽度独立进行缩放,因此可能不会保持该内容的原始纵横比。也就是说,为了完全填充输出区域,内容可能会失真。

    下面的图像阐释了不同的 Stretch 设置。

    image

     

    参考资料:

    Color 结构
    http://msdn.microsoft.com/zh-cn/library/system.windows.media.color.aspx

    LinearGradientBrush 类
    http://msdn.microsoft.com/zh-cn/library/system.windows.media.lineargradientbrush.aspx

    使用纯色和渐变进行绘制概述
    http://msdn.microsoft.com/zh-cn/library/ms754083.aspx

    November 24

    Silverlight学习笔记--绘制与着色(上)

    最近通过看WebCase的录像来学习Silverlight,为了避免学了后面忘了前面,把录像中的重点整理成笔记记录下来。

    通过录像来学习Silverlight,我推荐看苏鹏讲的Silverlight探秘系列课程,这个系列课程已经讲到50多讲了。由浅入深,而且连绵不断,确实很有帮助。

     

    这篇博客是对 苏鹏讲解的“Silverlight探秘系列课程(3):绘制与着色”的笔记,网上有很多地方都有这个课程下载,我就不给链接地址了。不过推荐使用 iReaper 来下载讲座视频。

     

    椭圆

    <Ellipse
        Height="200" Width="200"
        Stroke="Black" StrokeThickness="10" Fill="SlateBlue"  />

    image

    • Stroke 属性来指定用于绘制椭圆轮廓的 Brush。
    • StrokeThickness 属性指定椭圆轮廓的粗细。
    • Fill 属性来指定用于绘制椭圆内部区域的 Brush。

    相对于父控件的定位可以有下面2种:

    情况1:

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	x:Class="SilverlightStudy.MainPage"
    	Width="640" Height="480">
    <Ellipse 
          Height="200" Width="250"
          Stroke="Black" StrokeThickness="10" Fill="SlateBlue" 
    	  HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,12,0,0" />
    </UserControl>

    情况2:

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	x:Class="SilverlightStudy.MainPage"
    	Width="640" Height="480">
    <Canvas xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">	
    <Ellipse 
          Height="200" Width="250"
          Stroke="Black" StrokeThickness="10" Fill="SlateBlue" 
    	  Canvas.Left="50" Canvas.Top="30" />
    </Canvas>
    </UserControl>


    图像的遮挡
    如果没有指定ZIndex, 则后画的遮挡了先画的;如果指定了ZIndex :则给定 element 的 value 越大,element 在前景中出现的可能性就越大。同样,如果 element 具有一个相对较低的 value,则 element 将可能出现在背景中。例如,具有 value 为 5 的 element 将出现在具有 value 为 4 的 element 的上方,后者又将出现在具有值为 3 的 element 的上方,依此类推。允许负值,并且这些负值也适用此优先级模式。 如下图,

     

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	x:Class="SilverlightStudy.MainPage"
    	Width="640" Height="480">
    <Canvas >	
    <Ellipse
          Canvas.ZIndex="3"
          Canvas.Left="5" Canvas.Top="5"
          Height="200" Width="200"
          Stroke="Black" StrokeThickness="10" Fill="Silver" />
    
      <Ellipse
          Canvas.ZIndex="2"
          Canvas.Left="50" Canvas.Top="50"
          Height="200" Width="200"
          Stroke="Black" StrokeThickness="10" Fill="DeepSkyBlue" />
    
      <Ellipse
          Canvas.ZIndex="-1"
          Canvas.Left="95" Canvas.Top="95"
          Height="200" Width="200"
          Stroke="Black" StrokeThickness="10" Fill="Lime" />
    </Canvas>
    </UserControl>
    效果图如下:

    image

    线条

    <Line X1="280" Y1="10" X2="10" Y2="280" Stroke="Black" StrokeThickness="5"/>

    使用 Line 元素的 X1 和 Y1 属性设置线条起点,并使用 Line 元素的 X2 和 Y2 属性来设置线条终点。最后,设置 Line 元素的 Stroke 和 StrokeThickness,因为没有笔画的线条是看不见的。为线条设置 Fill 元素将毫无意义,因为线条没有内部区域。

    矩形

     <Rectangle
        Width="200"
        Height="100"
        Fill="Blue"
        Stroke="Black" StrokeThickness="4"
        RadiusX="20" RadiusY="20"/>

    image

    若要绘制矩形圆角,请指定可选的 RadiusX 和 RadiusY 属性。RadiusX 和 RadiusY 属性设置用于使矩形的角变圆的椭圆的 x 轴和 y 轴半径。这两个的默认值为0,即,没有圆角。

    封闭多边形

    <Polygon Points="10,10 10,110 110,110 110,85 45,10"
          Stroke="Black" StrokeThickness="10" Fill="LightBlue"/>

    image

    注意,在可扩展应用程序标记语言 (XAML) 中,我们使用由逗号分隔的 x 和 y 坐标对组成的空格分隔列表来设置 Points 属性。即使用简单表示法, x1,y1 x2,y2 ... xn,yn。

    未封闭多边形

    我们还是使用上面的点,注意,这时候 Fill 意义不大,我们就没设置,这个值也是可设置的

    <Polyline Points="10,10 10,110 110,110 110,85 45,10"
          Stroke="Black" StrokeThickness="10" />

    效果如下:

    image

    增加 Fill="LightBlue" 带来的效果如下:

    image

     

    路径

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	x:Class="SilverlightStudy.MainPage"
    	Width="640" Height="480">
    <Canvas>
    	<Path Data="M0,0 L11.5,0 11.5,30 5.75,40 0,30z"
          Stroke="Black" Fill="SlateBlue" Canvas.Left="118" Canvas.Top="57" 
    	  UseLayoutRounding="False" />
    	  
    	<Path Data="M 10,100 C 10,300 300,-200 250,100z"
          Stroke="Red" Fill="Orange" Canvas.Left="54" Canvas.Top="167" 
    	  UseLayoutRounding="False" />
    
            <Path Data="M 0,200 L100,200 50,50z"
          Stroke="Black" Fill="Gray" Canvas.Left="397" Canvas.Top="66" 
    	  UseLayoutRounding="False" />
    </Canvas>
    </UserControl>

    image

    上面 Path 元素的 Data 属性描述的是路径,这里的路径描述使用几何迷你语言命令,这个语言命令规范如下图:

    image

    参考资料:

    WPF 中的形状和基本绘图概述
    http://msdn.microsoft.com/zh-cn/library/ms747393.aspx

    November 23

    WPF,Silverlight 中的 xmlns,xmlns:x

    我们在每一个XAML文件中都可以看到下面的信息:

    Silverlight应用
    <
    UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > </UserControl>
    WPF应用
    <
    Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> </Grid> </Window>

          XAML文件首先是一个XML文件。为了验证自己和子元素的合法性,即保证在XML文档中的元素和属性名字的合法性,XML规范了XML命名空间,参看下面文档:

    http://www.opendl.com/openxml/w3/TR/xml-names/xml-names-gb.html

          上面例子中,xmlns 属性专门指默认的 xmlns 命名空间。在默认的 xmlns 命名空间中,可以不使用前缀指定标记中的对象元素。目前对于大多数的 WPF 应用程序以及 SDK 的 WPF 部分中给出的几乎所有示例版本的WPF,Silverlight 2.0 (含)以后的开发工具, 默认的 xmlns 命名空间均映射到 WPF 命名空间 http://schemas.microsoft.com/winfx/2006/xaml/presentation

          xmlns:x 属性指示另外一个 xmlns 命名空间,该命名空间映射 XAML 语言命名空间 http://schemas.microsoft.com/winfx/2006/xaml 。在具有此映射的文件的标记中引用时,XAML 规范定义的所需语言组件带有 x: 前缀。

    如下图所示:

    <Page 根元素的开始对象元素
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 默认 (WPF) 命名空间
    就类似于如下的C#代码:
    using System.Windows;
    using System.Windows.Automation 
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives 
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Forms.Integration 
    using System.Windows.Ink 
    using System.Windows.Media.Animation 
    using System.Windows.Media.Effects 
    using System.Windows.Media.Media3D 
    using System.Windows.Media.TextFormatting 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 这是XAML语言命名空间,用于映射System.Windows.Markup命名空间中的类型,而且它也定义了XAML编译器或解析器中的一些特殊的指令。这些指令通常是作为XML元素的特性出现的,因此它们看上去像宿主元素的属性,但实际上并不是如此。
    x:Class="MyNamespace.MyPageCode" 分部类声明,它将标记连接到此分部类中定义的任何代码隐藏
    > 根的对象元素的末尾,但由于页面包含子元素,因此尚未结束

     

    参考资料:

    WPF学习笔记1:XAML之NameSpace
    http://www.cnblogs.com/jacksonyin/archive/2008/02/25/1080336.html

    HTML xmlns 属性
    http://www.w3school.com.cn/tags/tag_prop_xmlns.asp

    XAML 概述
    http://msdn.microsoft.com/zh-cn/library/ms752059.aspx

    《WPF揭秘》 2.3  命名空间
    http://book.csdn.net/bookfiles/677/10067721293.shtml

    November 12

    Silverlight 版的电子表

    程序执行的效果图:

    image

    这个程序改编自:webabcd 的 Silverlight 1.0 同样程序。

    http://www.cnblogs.com/webabcd/archive/2007/09/17/895328.html 

    我这里把 Silverlight 1.0 的程序改成 Silverlight 3.0 的程序了。中间的逻辑,原先是JavaScript写的,现在变成C#写的了。

    程序是用VS2010 beta 写的, 使用的是 VS2010 默认创建的 Silverlight 项目来编写的。 对其中改动的部分代码如下:

    MainPage.xaml 文件

    <UserControl x:Class="ClockSilverlightApp.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400" Loaded="UserControl_Loaded">
    
        <Canvas
    	xmlns="http://schemas.microsoft.com/client/2007"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	Width="180" Height="150"
    	Background="#0030628D"
    	x:Name="Page" >
            <Rectangle x:Name="Frame" Width="180" Height="150" Stroke="#FF000000" StrokeThickness="1" RadiusX="20" RadiusY="15">
                <Rectangle.Fill>
                    <LinearGradientBrush EndPoint="0.5,1.1" StartPoint="0.5,-0.1">
                        <GradientStop Color="#FF259888" Offset="0"/>
                        <GradientStop Color="#FF259888" Offset="0.981"/>
                        <GradientStop Color="#FFC87947" Offset="0.416"/>
                        <GradientStop Color="#FFC87947" Offset="0.636"/>
                    </LinearGradientBrush>
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle x:Name="Panel" Width="164" Height="134" Fill="#7F91B52C" Stroke="#FFA2AEBF" RadiusX="50" RadiusY="15" Canvas.Left="8" Canvas.Top="8" StrokeThickness="2"/>
    
            <Path x:Name="Line1" Width="163" Height="1" Fill="#FF100888" Stretch="Fill" Stroke="#FF1B510C" Canvas.Left="8" Canvas.Top="92" Data="M33.50029,83.29705 L161.89657,83.297051"/>
            <Path x:Name="Line2" Width="1" Height="49" Fill="#FF100888" Stretch="Fill" Stroke="#FF1B510C" Canvas.Left="56" Canvas.Top="92" Data="M81.450752,138.29705 L81.450752,90.29705"/>
            <Path x:Name="Line3" Width="1" Height="49" Fill="#FF100888" Stretch="Fill" Stroke="#FF1B510C" Canvas.Left="110" Canvas.Top="92" Data="M118.30501,164.29698 L118.30501,116.29699"/>
    
            <TextBlock x:Name="Month" Width="16" Height="19" Canvas.Left="30" Canvas.Top="92" TextWrapping="Wrap" Foreground="#FF100888" Text="月"/>
            <TextBlock Width="16" Height="19" Canvas.Left="78" Canvas.Top="92" TextWrapping="Wrap" x:Name="Day" Foreground="#FF100888" Text="日"/>
            <TextBlock Width="30" Height="19" Canvas.Left="129" Canvas.Top="92" TextWrapping="Wrap" x:Name="Week" Foreground="#FF100888" Text="星期"/>
    
            <TextBlock x:Name="txtMonth" Width="19" Height="19" Canvas.Left="28" Canvas.Top="111" TextWrapping="Wrap" Foreground="#FF100888" Text="12"/>
            <TextBlock x:Name="txtDay" Width="20.5" Height="19" Canvas.Left="77" Canvas.Top="111" TextWrapping="Wrap" Foreground="#FF100888" Text="31"/>
            <TextBlock x:Name="txtWeek" Width="20" Height="19" Canvas.Left="133" Canvas.Top="111" TextWrapping="Wrap" Foreground="#FF100888" Text="六"/>
    
            <TextBlock x:Name="txtHour" Width="48" Height="48" Canvas.Left="14.5" Canvas.Top="38" TextWrapping="Wrap" FontSize="36" Foreground="#FF100888" Text="23"/>
            <TextBlock x:Name="txtMinute" Width="48" Height="48" Canvas.Left="68.5" Canvas.Top="38" TextWrapping="Wrap" FontSize="36" Foreground="#FF100888" Text="59"/>
            <TextBlock x:Name="txtSecond" Width="49" Height="48" Canvas.Left="122" Canvas.Top="38" TextWrapping="Wrap" FontSize="36" Foreground="#FF100888" Text="59"/>
    
            <TextBlock x:Name="Colon1" Width="9.5" Height="27" Canvas.Left="62.5" Canvas.Top="48" TextWrapping="Wrap" Foreground="#FF100888" Text=":" FontSize="20"/>
            <TextBlock x:Name="Colon2" Width="12" Height="27" Canvas.Left="116.5" Canvas.Top="48" TextWrapping="Wrap" Foreground="#FF100888" Text=":" FontSize="20"/>
    
            <TextBlock x:Name="Copyright" Width="88" Height="16" Canvas.Left="16" TextWrapping="Wrap" FontSize="12" Canvas.Top="22" Foreground="#FF100888" Text="郭红俊 clock" MouseLeftButtonDown="Copyright_MouseLeftButtonDown" MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave" />
            <TextBlock x:Name="FullScreen" Width="88" Height="16" Canvas.Left="106" TextWrapping="Wrap" FontSize="12" Canvas.Top="22" Foreground="#FF100888" Text="FullScreen"  MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave" MouseLeftButtonDown="FullScreen_MouseLeftButtonDown" />
        </Canvas>
    
    </UserControl>

    MainPage.xaml.cs 文件

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Threading;
    using System.Windows.Browser;
    
    namespace ClockSilverlightApp
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
                dicWeek.Add(DayOfWeek.Friday, "");
                dicWeek.Add(DayOfWeek.Monday, "");
                dicWeek.Add(DayOfWeek.Saturday, "六");
                dicWeek.Add(DayOfWeek.Sunday, "");
                dicWeek.Add(DayOfWeek.Thursday, "");
                dicWeek.Add(DayOfWeek.Tuesday, "");
                dicWeek.Add(DayOfWeek.Wednesday, "");
    
            }
    
            private static readonly Dictionary<DayOfWeek, string> dicWeek = new Dictionary<DayOfWeek, string>();
    
    
            /// <summary>
            /// 定时更新前段显示信息事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void enableClock(object sender, EventArgs e)
            {
                DateTime dt = DateTime.Now;
                this.txtMonth.Text = string.Format("{0:00}", dt.Month);
                this.txtDay.Text = string.Format("{0:00}", dt.Day);
                this.txtWeek.Text = dicWeek[dt.DayOfWeek];
                this.txtHour.Text = string.Format("{0:00}", dt.Hour);
                this.txtMinute.Text = string.Format("{0:00}", dt.Minute);
                this.txtSecond.Text = string.Format("{0:00}", dt.Second);
    
            }
    
            DispatcherTimer timer = new DispatcherTimer();
    
    
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                enableClock(null, null);
                timer.Interval = new TimeSpan(0,0,1);
                timer.Tick += new EventHandler(enableClock);
                timer.Start();
            }
    
            private void Copyright_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                HtmlPage.Window.Navigate(new Uri("http://www.csdn.net/"), "new");
            }
    
            private void TextBlock_MouseEnter(object sender, MouseEventArgs e)
            {
                if (sender == null) return;
                TextBlock tb = sender as TextBlock;
                if (tb == null) return;
                // TextBlock.foreground
                tb.Foreground = new SolidColorBrush(Colors.Red);
                // TextBlock.textDecorations
                tb.TextDecorations = TextDecorations.Underline;
                tb.Cursor = Cursors.Hand;
            }
    
            private void TextBlock_MouseLeave(object sender, MouseEventArgs e)
            {
                if (sender == null) return;
                TextBlock tb = sender as TextBlock;
                if (tb == null) return;
                // TextBlock.foreground
                tb.Foreground = new SolidColorBrush(Color.FromArgb(255,16,8,136));
                // TextBlock.textDecorations
                tb.TextDecorations = null;
                tb.Cursor = Cursors.Arrow;
            }
    
            private void FullScreen_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;
            }
        }
    }

    其他文件没有变化。

    这个程序我觉得挺适合初学者做出第一个有点意思的Silverlight程序。所以就把它改写成Silverlight 3 的程序了。

    VS2010中的Silverlight项目中的文件

    我们使用 VS2010 新建 Silverlight 项目时,会有下面选项框:

    image

    (图1)

    这里VS2010支持的 Silverlight 项目类型有以下三种:

    • ASP.NET Web Application Project
    • ASP.NET Web Site
    • ASP.NET MVC Web Project

    VS2010支持的 Silverlight 版本只由3.0。

    以ASP.NET Web Application Project 项目类型为例,以下为系统默认给我们建立的文件:

    image

    (图2)

     

    下面我们就对其中的一些有代表性的文件作以介绍:

     

    XAP 文件是啥?

    以上面项目的 HelloWorldSilverlight.xap 文件为例,我们把它后缀修改为 zip 文件,用 rar 打开就可以看到下面信息:

    image

    (图3)

    HelloWorldSilverlight.xap 就是编译打包后的 HelloWorldSilverlight 项目的输出文件。 只不过压缩了一下而已。

    这个文件包括了Silverlight应用程序所需的一切文件,如程序集、资源文件等。这里的xap后缀没有任何特殊的意义,仅仅是Silverlight应用程序编译后打包文件的扩展名而已,本质上它是一个标准的zip压缩文件。

    这个打包文件中的 AppManifest.xaml 文件相当于一个清单,以上面的代码为例,这个文件的内容就是:

    <Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="HelloWorldSilverlight" EntryPointType="HelloWorldSilverlight.App" RuntimeVersion="3.0.40818.0">
      <Deployment.Parts>
        <AssemblyPart x:Name="HelloWorldSilverlight" Source="HelloWorldSilverlight.dll" />
        <AssemblyPart x:Name="System.Windows.Controls.Data.Input" Source="System.Windows.Controls.Data.Input.dll" />
        <AssemblyPart x:Name="System.ComponentModel.DataAnnotations" Source="System.ComponentModel.DataAnnotations.dll" />
      </Deployment.Parts>
    </Deployment>

    Silverlight 开始执行时,加载入口在哪里,就在上面定义中的 EntryPointAssemblyEntryPointType

    System.ComponentModel.DataAnnotations.dll 文件提供了用于为 ASP.NET 动态数据控件定义元数据的属性类。 

    System.Windows.Controls.Data.Input.dll  文件提供了可用于Silverlight的控件。

     

    我们如何修改编译打包的HelloWorldSilverlight.xap 文件的一些信息,我们可以通过打开 HelloWorldSilverlight 项目属性页面,如下图:

    其中 Silverlight 属性页就可以让我们修改 生成的XAP文件名。

    image

     

    我们在图2中可以看到 HelloWorldSilverlight.Web WEB项目没有引用 HelloWorldSilverlight 项目,那为啥 HelloWorldSilverlight 项目 修改后可以及时同步到HelloWorldSilverlight.Web  呢?

    原因:我们在 HelloWorldSilverlight.Web  项目的属性窗口中可以看到关于 Silverlight Application 的设置,如下:

    image 

    点击 Add 出现的窗口:

    image

    在这里我们可以指定是否使用默认的 ClientBin 目录。 需要引用那些 Silverlight 项目。是否启用调试等等。

     

    以上全部为VS2010Beta2的截图,也许VS2010最终版本会有所变化。

    参考资料:

    一步一步学Silverlight 2系列(1):创建一个基本的Silverlight应用
    http://www.cnblogs.com/Terrylee/archive/2008/03/07/Silverlight2-step-by-step-part1.html

    稳扎稳打Silverlight(1) - 1.0实例之电子表

    http://www.cnblogs.com/webabcd/archive/2007/09/17/895328.html

    Silverlight 2应用程序中XAP文件揭秘
    http://www.cnblogs.com/Terrylee/archive/2008/07/11/xap-file-revelation-in-silverlight-2.html

    Silverlight.js 参考
    http://msdn.microsoft.com/zh-cn/library/cc838126(VS.95,loband).aspx

    November 06

    几个网页制作的小技巧

    让浏览器在保存页面时失败

    在页面源文件上增加下面一行代码,保存页面时,就会报错误:

    <noscript><iframe src="*.html"></iframe></noscript>

    防止被人frame 或者 iframe 包含我们的页面:
    <script language="javascript"><!--
        if (top.location != self.location) top.location = self.location;
    //--></script>

    脚本出错时,也不提醒

    <script language="javascript"><!-- 
        function killErrors() {
            return true;
        }
        window.onerror = killErrors; 
    //--></script>
    自动显示最后更新时间
    <script language="JavaScript">
    <!--hide script from old browsers
    document.write("本页最后更新日期: " + document.lastModified + "")
    // end hiding -->
    </script>
    "document.lastModified” 得到的是文件最后更新时间,这样我们就不用更新文件的时候,再更新对应页面文本了。