2011年7月29日 星期五

Expression Blend(22)- 使用DataGrid進行資料繫結

Expression Blend 4有一個Sample Data功能,可以建立開發階段的資料,以下展示如何建立範例資料,然後透過DataGrid來進行繫結。
  • 建立WPF應用程式
  • New Sample Data
image
  • OK
image
  • 雙擊Collection變更名稱為Employees,雙擊Collection下的property1,變更名稱為EmpID;雙擊Collection下的property2,變更名稱為EmpName,並變更資料型別為sring。Data頁目前看起來如:
image
  • 從Asserts找到DataGrid,拖曳到設計畫面
image
  • Edit Sample Values ,自行編輯範例所需資料image
  • 將Collection (Employees)拖曳到DataGrid上放開
image
  • DataGrid就會自動顯示資料
image
  • Data-> Details Mode,切換成Details Mode,將EmpID拖曳到畫面DataGrid下方,便會自動建立Binding
image
  • 按相同方式,將EmpName拖曳到畫面DataGrid下方
  • 按F5執行,點選DataGrid中任一筆資料,明細資訊就會顯示在下方
image

Expression Blend(21)- 使用Property Binding

Property Binding可以讓你同步兩個不同控制項的屬性值。以下將TextBlock的FontSize屬性繫結到Slider的Value。

  • 加入一個TextBlock控制項,一個Slider控制項
  • 設定Slider控制項Minimun與Maximum屬性值來決定字型的最大與最小值,Value值決定字型大小

image

  • TextBlock控制項-> Text頁->Font Size->Advanced options-> Element Property Binding

image

  • 選畫面上的Slider

image

  • 選Value

image

  • 按F5執行,當拉動Slider,字型就會變動

Expression Blend(20)- 使用VisualStateManager播放動畫(Silverlight)

 

你可以使用VisualStudioManager根據狀態(State)的變化來建立基本的動畫,例如紅綠燈會變化不同的燈號,進入不同的狀態。

以下說明如何使用VisualStateManager播放動畫

  • 建立一個Silverlight應用程式
  • 將預設的Grid轉成Canvas

image

  • 準備一張紅綠燈的底圖,紅綠黃三個顏色要塗暗些。再使用Ellipse工具畫三個圓,塗上較亮的紅綠黃三色,name屬性分別設redCircle、greenCircle 與yellowCirlce。

image

  • 將三個圓移動到紅綠燈上,蓋掉暗部的紅綠黃三燈。

image

  • 設定redCircle、greenCircle 與yellowCirlce的Visibility為Collapsed,預設先隱藏起來

image

  • Add state group

image

  • Add state

image

  • 改名為Red

image

  • 重複Add State,改名Green、Yellow

image

  • 按F6切換到動畫設計模式
  • 移動playhead到0秒,選redCircle,將Visibility設為Visible

image

  • 移動playhead到1秒,選redCircle,將Visibility設為Collipsed,選greenCircle,將Visibility設為Visible

image

  • 移動playhead到2秒,選greenCircle,將Visibility設為Collipsed,選yellowCircle,將Visibility設為Visible

image

  • 結束動畫錄製
  • 加一個Button到畫面
  • 將GotoStateAction拉到Button上放開

image

  • 設StateName為Yellow

image

  • 按F5執行,當你點選Button,便撥放動畫,先亮紅燈,依序亮綠、黃燈。

2011年7月28日 星期四

WCF教學(11) - MessageContract

MessageContract可以用來變更SOAP封包的長像,例如想把資料放在Soap封包Header區段。以實例說明。

  • File->New Website->WCF Service->MyWCFService
  • 在ISerivce.cs檔加入一個Employee Class

public class Employee
{
    public string Name { get; set; }
    public int Age { get; set; }
}

  • 在IService中加一個Operation
[ServiceContract]
public interface IService
{
    [OperationContract]
    void GetEmployee(Employee emp);
    //略   
}
  • 在Service.cs實作

image

  • 拿掉GetEmployee其中的code

public void GetEmployee(Employee emp)
    {
    }

  • 按F5執行
  • 使用Visual Studio 2010執行wcftestclient.exe,試著呼叫GetEmployee方法

image

  • 切到XML檢視,預設Employee的Name與Age都會放在封包Body區段

image 

  • 修改Employee類別,加上MessageContract、MessageHeader、MessageBodyMember

[MessageContract]
public class Employee
{
    [MessageHeader]
    public string Name { get; set; }
    [MessageBodyMember]
    public int Age { get; set; }
}

  • 按F5執行,切到XML檢視,Employee的Name會放到Header,Age會放到Body

image

WCF教學(10) - 設計Service、Operation 與Data Contract

設計服務合約 (Service Contract)與作業合約(Operation Contract)都可以利用attribute來變更命名空間,或是名稱,我們來看看常用的attribute。
image
  • 使用Visual Studio 2010 Command Prompt,執行wcftestclient.exe
  • Add Service
image
  • 輸入服務URL
image
  • 預設範本中提供一個IService Contract,以及有一個GetData Operation。你可以雙擊GetData,輸入參數,並按Invoke按鈕叫用服務。
image
  • 修改IService.cs,ServiceContract與GetData Operation,加上Name與Namespace
[ServiceContract(
Name = "IContract",
Namespace = "http://www.test.com"
)]
public interface IService
{
    [OperationContract(
    Name = "DoGetData", Action = "http://www.test.com/DoGetData")]
    string GetData(int value);
    [OperationContract]
    CompositeType GetDataUsingDataContract(CompositeType composite);
}
  • 重複以上步驟,使用Visual Studio 2010 Command Prompt,執行wcftestclient.exe,服務的合約與Operation的名稱便會更改
image
  • 加一個Console Client到Solution,ConClient
  • ConClient,Add Service  Reference->Discovery->OK
  • 修改Main,設定Service Contract與Operation Contract名稱會影響Proxy類別的命名,因此Main程式要改如下,才可叫用服務
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConClient
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceReference1.ContractClient proxy = new ServiceReference1.ContractClient();
            Console.WriteLine(proxy.DoGetData(10));
        }
    }
}

預設使用DataContract時,只有有標示DataMember的成員才會被序列化,設計DataContract時也可以套用很多attribute
  • 修改MyWCFService,IService.cs,預設的CompositeType class,加上Namespace
[DataContract(Namespace = "http://www.aaa.com")]
public class CompositeType
{ //略
  • 執行svc,然後在 url 後方輸入?xsd=xsd0
  • 可以看到namespace變更了
image
image
  • 修改程式碼,設定DataMember的Name與Order
[DataContract(Namespace = "http://www.aaa.com")]
public class CompositeType
{
    bool boolValue = true;
    string stringValue = "Hello ";
    [DataMember(Name = "myBoolValue", Order = 1)]    public bool BoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }
   [DataMember(Name = "myStringValue", Order = 0)]    public string StringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }
}
image
變更DataContract不會影響到Proxy的產生,因此ConClient程式不用做任何修改還是可以正常執行。

WCF教學(9) - 使用Routing與備援清單

這個練習將設計一個RsHost做Routing,聽在8081 port,收到ConClient請求後,將請求導向接聽8080 port的MyWCFService
  • File->New Website->WCF Service->MyWCFService
  • MyWCFService, 設port使用8080
image
  • File->Add->new Project->加入Console Application做為Routing Service Host,名為RsHost
  • RsHost,加入參考System.ServiceModel, System.ServiceModel.Routing.dll
  • RsHost,加入app.config檔,並加入以下內容
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="System.ServiceModel.Routing.RoutingService"
      behaviorConfiguration="routingData">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8081/routing/"/>
          </baseAddresses>
        </host>
        <endpoint address="requestReply"
        binding="basicHttpBinding"
        contract="System.ServiceModel.Routing.IRequestReplyRouter"/>
      </service>
    </services>
    <client>
      <endpoint name="epMyWCFService"
      address="http://localhost:8080/MyWCFService/Service.svc"
      binding="basicHttpBinding"
      contract="*"/>
    </client>
    <behaviors>
      <serviceBehaviors>
        <behavior name="routingData">
          <routing filterTableName="routingTable" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <routing>
      <filters>
        <filter name="MatchAllDefaultFilter" filterType="MatchAll" />
      </filters>
      <filterTables>
        <filterTable name="routingTable">
          <add filterName="MatchAllDefaultFilter"
          endpointName="epMyWCFService"/>
        </filterTable>
      </filterTables>
    </routing>
  </system.serviceModel>
</configuration>
  • RsHost,Main方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Routing;
namespace RsHost
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("RS is running...");
            ServiceHost myServiceHost = new ServiceHost(typeof(RoutingService));
            myServiceHost.Open();
            Console.Read();
        }
    }
}
  • 測試執行RsHost專案可以執行,不會出現錯誤
  • File->Add->new Project->加入Console Application做為Client,名為ConClient
  • ConClient,Add Service Reference->Discover->OK
  • ConClient,Main Method
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.ReadLine();
            ServiceReference1.ServiceClient c = new ServiceReference1.ServiceClient();
            Console.WriteLine(c.GetData(10));
        }
    }
}

<client>
            <endpoint address="http://localhost:8081/routing/requestReply"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService"
                contract="ServiceReference1.IService" name="BasicHttpBinding_IService" />
        </client>
  • 設定同時執行三個專案,請注意專案順序,愈上面愈先執行
image
  • Run,ConClient可以取得服務回傳的結果
image
若服務掛點,在WCF4中我們可以設定備援清單,將請求繞送到其它服務執行。例如以下步驟,修改服務接聽9999 port ,但實際上這個服務並不存在,ConClient透過Routing Service叫用9999埠的服務,利用備援清單,導向接聽8080的服務。
  • RsHost,修改RSHost app.config檔,<client>下,加入 endpoint,聽port 9999,<Clinet>區段看起來如
<client>
     <endpoint name="epMyWCFService"
     address="http://localhost:8080/MyWCFService/Service.svc"
     binding="basicHttpBinding"
     contract="*"/>
     <endpoint name="Dead"
     address="http://localhost:9999/MyWCFService/Service.svc"
     binding="basicHttpBinding"
     contract="*"/>
   </client>
  • RsHost,在app.config,<routing>下,加
   <backupLists>
        <backupList name="bklist">
          <add endpointName="epMyWCFService"/>
        </backupList>
      </backupLists> 
  • RsHost,在app.config,修改filter,endpointName="Dead"  backupList="bklist"
<filterTables>
       <filterTable name="routingTable">
         <add filterName="MatchAllDefaultFilter"      
              endpointName="Dead"  backupList="bklist"  />
       </filterTable>
     </filterTables>
  • Run,ConClient可以取得服務回傳的結果

2011年7月27日 星期三

Expression Blend(19)- 使用ControlStoryboardAction behavior播放動畫

Expression Blend(17)- Path 動畫範例中,我們利用Storyboard1.Begin()程式碼在UserControl_Loaded事件執行動畫。不過,在Expression Blend4中提供一個Conditional Behavior可以用來控制Storyboard。例如延續Expression Blend(17)- Path 動畫範例

  • 註解以下程式
private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
           
            //Storyboard1.Begin();
        }
  • 加一個Button
  • Asserts –> Behaviors –> 將ControlStoryboardAction behavior拖曳到Button上放開

image

  • 在屬性視窗設定ControlStoryboardAction 的Storyboard

image

  • F5執行,當你點選Button,才會撥放動畫。

Expression Blend(18)- Motion Path 動畫(WPF)

Expression Blend(17)- Path 動畫範例中,使用PathListBox來設計動畫。相同的情境若要改用WPF,可以使用Motion Path 來完成,而且更簡單…。
此範例僅適用於WPF
  • 建立WPF應用程式
  • 使用Pencil 畫出一條線
image
  • 加一個Ellipse
  • 將畫出的Path轉換成Motion Path
image
  • 選擇Ellipse
image
  • 按F6切換到動畫設計模式,此時試著執行,Ellipse就會隨著線段移動
image

Expression Blend(17)- Path 動畫(Silverlight)

此範例僅適用於Silverlight
這個範例要設計一個Ellipse隨著一條Path來進行移動。
  • 先使用Pen畫出一條Path,並加上一個Ellipse,塗滿藍色
image
  • 選取Path,Object->Path->Make Layout Path ,Objects and Timelines視窗就會產生一個PathListBox
  • 將Ellipse拖曳到PathListBox下
image
  • 設定PathListBox的Capacity為100,Start為1%
image
  • 產生Storyboard
image
  • 移動黃色拉趕到適當秒數,決定要在幾秒中從最左邊移動到最右邊,然後設定PathListBox的Capacity為100%
image
  • 結束動畫錄製
  • 產生UserControl的Loaded事件,點選畫面上的UserControl,從屬性視窗選Events(閃電),然後在Loaded項目雙擊
image
  • 加入程式
private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e) {
              Storyboard1.Begin();
        }
  • 按F5執行,Ellipse就會隨著Path移動
image

總網頁瀏覽量