2015年3月23日 星期一

sTouch Board is now available on Google Play!

We launched an interactive app in Google Play
https://play.google.com/store/apps/details?id=sTouch.Android.Client&hl=en-us


sTouch Board- Getting Started
                                                 

                                                               

sTouh Board Client allows users to turn their Android tablet/phone into an interactive whiteboard. With the App you can view shared content, control your presentation device, and annotate over any content.

How To Use:
1. Install sTouch Board Windows version: The sTouch Board Client App requires the Windows version of sTouch Board software installed on your Windows device. You can download from here: http://www.stouchtech.com/#!download/c12ug

2. Network Environment: Make sure sTouch Board and sTouch Board Client are on the same network.

3. Connect to sTouch Board : Select the room you from pairing list, and click JOIN.
Please check software user manual for more detail:
http://media.wix.com/ugd/4ee221_94f3d4c3b321492eabe396860db8c6cc.pdf

We also provide interactive solutions for School Education/Office Presentation/Home Entertainment, please see the following components:

1. sTouch TV: It is the most cost effective solution for large touch screen in the world. Easy to set up! Easy to use! You can draw, write and play on the TV.

2. sTouch Whiteboard : It is a low-cost solution that simply turns a traditional whiteboard or projector surface into an interactive whiteboard.

3. sTouch Board: It is image-based, simple, intuitive whiteboard App available for Windows 8/Windows 7 system.
Features include:
- Drawing Tools - Color pens, highlighter pen, eraser, etc
- Present - Import document files or images into the app to make great presentation
- Sharing and Interactive - Broadcast your screen content and interact with remote devices
- Record - Ability to record and capture your screen
- Annotate - Annotate directly on the desktop screen

For more details, please refer the link: http://www.stouchtech.com/

2011年2月9日 星期三

事件的深入分析(function pointer, delegate, event, EventHandler)

Function pointer(函數指標)
C/C++ 若要設計事件(Callback function), 可利用function pointer來完成, 其詳細作法可參考Callback Function


Delegate(委託)
delegateC#特殊的類別, 它可以封裝一個函數, 但與一般類別不同之處,delegate擁有一個簽名(可以代表函式的引數類型和回傳值類型). delegate實現的功能和C/C++中的函數指標十分相似.

C/C++ :
    void (*UpdateCallback)(double time);
 
C# :
    delegate void UpateDelegate(double time);

雖然delegate類似於函式指標(function pointer), 不過還是有很多不同之處, 例如delegate具有物件導向和型別安全等特性
.

delegate用法
delegate的使用步驟如下:

1. 宣告委派型別 
宣告一個delegate的型別, 每個delegate型別封裝了函數的回傳類型,引數的數目, 和引數的類型, 如下面陳述式所示:
delegate void MessageDelegate(string str);

2. 定義一個符合委派型別的簽名方法, 可為 instance method 或 static method
public static void HelloFun(string str)
{
   Console.WriteLine("  Hello, {0}!", str);
}
public static void GoodbyeFun (string str)
{
   Console.WriteLine("  Goodbye, {0}!", str);
}

3. 建立委派物件, 並指定委派方法
delegate宣告後, 必須再將它實體化才能使用(和一般類別的使用方式一樣, 需先將物件實體化), 並指定所代表的函式, 但不需傳入引數, 如下面範例所示
static void Main(string[] args)
{
   MessageDelegate msDelegate = new MessageDelegate(HelloFun);
}

delegate同時也支援多點傳送(+=, -=), 因為繼承自System.MulticastDelegate類別, 你可以使用+= 運算子將多個方法綁定到同一個delegate, 當呼叫這個delegate的時候, 將依次呼叫其所綁定的方法. 當然你也可以使用 - = 運算子 將某個委派參考從委派清單中移除.

MessageDelegate msDelegate;
 msDelegate = new MessageDelegate(HelloFun);
 msDelegate += new MessageDelegate(GoodbyeFun);
 msDelegate -= new MessageDelegate(HelloFun);

4. 透過委派物件執行委派方法
如下所示:
msDelegate("Peter"); //等同msDelegate.invoke("Peter");


event
event的出現,是要避免使用delegate可能會破壞物件封裝性的問題,主要有下面兩點:
1.    delegate 可以隨意進行賦值操作, 若不小心使用將會移除所有委派
2.    為了讓delegate可以綁定特定的方法, 宣告時必須定義成public屬性, 但也因此破壞掉物件的封裝性, 因為類別的內外都可以呼叫delegate

考慮下面例子:
public class ButtonControl
{
        public delegate void ClickDelgate(object sender, EventArgs e);        
        public ClickDelgate ClickEvent; 
        public void OnFire(EventArgs e)
        {
            ClickEvent(this, e);
        }
}

static public void TexboxUpdate(object sender, EventArgs e)
{
     Console.WriteLine("Texbox update by button click");
 }

 static public void LabelUpdate(object sender, EventArgs e)
 {
      Console.WriteLine("Label update by button click");
 }

static void Main(string[] args)
{
ButtonControl btnCtrl = new ButtonControl();
      btnCtrl.ClickEvent = new ButtonControl.ClickDelgate(TexboxUpdate);
      btnCtrl.ClickEvent += new ButtonControl.ClickDelgate(LabelUpdate);
btnCtrl.ClickEvent = null;  //這將會移除所有委派
      btnCtrl.ClickEvent(null, new EventArgs()); //不應該讓使用者可以呼叫
}


而就觀察者模式來說, 也應避免下面這些情況:
  • 對於客戶端(觀察者), 應該只適合透過註冊/取消來操作自己對應的事件, 不應該隨意進行的賦值操作, 如果不小心將發佈者的delegate類別直接賦值null, 將會取消掉發佈者所有的通知列表
  • 發佈事件的通知應該由發佈者來觸發, 不應該讓客戶端可以呼叫
因此C#利用event來封裝delegate類型的變數, 所以在類別的外部, 使用者只能透過註冊“+=”和取消“-=” 來作事件的操作.

Event使用範例
將上述範例中, public ClickDelgate ClickEvent 加上 event修飾字
public class ButtonControl
{
        public delegate void ClickDelgate(object sender, EventArgs e);        
        public event ClickDelgate ClickEvent; 
        public void OnFire(EventArgs e)  
        {
            if (ClickEvent != null)
                ClickEvent(this, e);
        }
}

static void Main(string[] args)
{
   ButtonControl btnCtrl = new ButtonControl();

   //只能使用+=,-= 來對事件操作
   btnCtrl.ClickEvent += new ButtonControl.ClickDelgate(TexboxUpdate);
   btnCtrl.ClickEvent += new ButtonControl.ClickDelgate(LabelUpdate);
}

EventHandler
雖然 C# 語言允許event使用任一種delegate型別,但是 .NET Framework 對於使用於eventdelegate型別有更嚴格的規範, 因此另外定義出一個適當的delegate型別EventHandler, 語法如下:
public delegate void EventHandler(object sender, EventArgs e);

EventHandler 為預先定義的delegate, EventHandler會定義一個沒有傳回值的方法, 方法第一個參數的型別為 object, 表示引發事件的執行個體(如果是button1的click事件, 則sender就是button1), 而第二個參數的型別為EventArgs, 表示封裝事件的額外資訊.

EventHandler使用範例
public class ButtonControl
 {
        //利用EventHandler取代delegate void EventHandler(object sender, EventArgs e)
        public event EventHandler ClickEventHandler;  
        public void OnClick()
        {
            if (ClickEventHandler != null)
            {
                ClickEventHandler(this, new EventArgs());
            }           
        }
 }

自訂EventArgs
.NET Framework 2.0時引進EventHandler泛型版本,即 EventHandler<T>也就是如果你要自訂的 EventArgs 類別, 可以參考下面範例:
public event EventHandler<customeventargs> RaiseCustomEvent;

public class CustomEventArgs : EventArgs
{
    public CustomEventArgs(string s)
    {
        msg = s;
    }
    private string msg;
    public string Message
    {
        get { return msg; }
    } 
}

參考資料:
發行符合 .NET Framework 方針的事件
委派教學課程
事件教學課程
函數指標的進化論(下)
我對.NET中delegate和event區别的理解
談談委派 (Delegate)
C# 筆記:重訪委派-從 C# 1.0 到 2.0 到 3.0

2010年12月31日 星期五

WPF - Style使用

Style(樣式)
    Style主要就是透過屬性(Property)去自訂控制項的外觀, 尤其當我們需要相同的屬性套用在多個控制項時, Style會很方便.

比方在UI設計時, 常會讓UI具有某些相同的Style,例如:背景顏色,字型,控制項的顏色…等等.

使用Style的好處如下:
  • 可以方便使用者將一組屬性值(顏色,尺寸,動畫, 觸發方式等)套用到多個控制項的方式,這樣一來, 程式碼將變得簡潔.
  • 可集中在同一個地方作管理(ex: 資源 Resource), 好處如果以後想改變這些屬性, 只要在同一個地方更新即可
例如下面範例中, 有一個影音播放程式,如圖1所示, 其中UI上有三個外觀相同的按鈕, 在這程式碼當中, 如圖2所示, 如果不套用Style的話, 我們必需要將每一個控制項都設定一次相同的屬性, 這樣, 程式碼將會有很多重覆的部分, 而且, 萬一以後要變更其中一個屬性, 將要修改到很多地方

                                                       [圖1]具有一些相同屬性的Button



                                                          [圖2] 沒有套用Style


下面的範例中, 我們利用Style將上述程式碼中相同屬性抽離出來(StyleSetter組成的集合來設定目標屬性, 而每個Setter是由依存屬性和設定值組成), 並集中在Resource中. 程式碼將變得簡潔, 管理上也變的更方便, 如圖3所示.
                                                 [圖3] 套用Style


Style的共享與限定
你也可以將Style套用在不同的控制項上,如下所示:
<Style x:Key="controlStyle">
  <Setter Property="Control.Height" Value="30"/>
  <Setter Property="Control.Width" Value="75"/>
  <Setter Property="Control.Margin" Value="10"/>
  <Setter Property="Control.Background" 
                    Value="{StaticResource btnBackground}"/>
</Style>

<!-- Style套用在不同的控制項上-->
<Button x:Name="btnPlay" Grid.Column="0"
           Style="{StaticResource controlStyle}"
           Content="Play" Click="btnPlay_Click">
</Button>

<Label Grid.Column="1"
          Style="{StaticResource controlStyle}"
          Content="Text Block"/>
            
<Border Grid.Column="2"
           Style="{StaticResource controlStyle}"/>


或限定此Style只能給特定的控制項使用, 可用TargetType屬性指定, 例如你希望只有Button可套用此Style, 可寫成:
<Style x:Key="btnStyle" TargetType="{x:Type Button}">
     <Setter Property="Height" Value="30"/>
     <Setter Property="Width" Value="75"/>
     <Setter Property="Margin" Value="10"/>
     <Setter Property="Background" 
                Value="{StaticResource btnBackground}"/>
</Style>

若此Syle套用在非Button的控制項上, 將會產生編譯錯誤

Style繼承
Style之間可以互相繼承, 如果要這樣做, 您可以使用一個樣式做為基礎來建立新樣式, 並利用BasedOn屬性來繼承
<Style x:Key="btnStyleWithBold" 
          BasedOn="{StaticResource btnStyle}"
   <Setter Property="Button.FontWeight" Value= "Bold"/>
</Style>

另外, Style除了可用來設定控制項的屬性(Property)之外, 還可以運用在下列幾個地方
  • 設定觸發方式(Trigger)
  • 設定動畫(Animation)
  • 設定樣板(Template)
相關範例, 可參考: MSDN-設定樣式與範本