Wednesday, March 23, 2016

Update UI from Background Thread

有玩過 Threading 既都可能知道, background thread 係唔可以直接 update UI 既野.
今次學玩 C#, 當然又要研究下.  So far 都好多方法..

1) 用 Application.Current.Dispatcher.BeginInvoke, 簡單直接了當:

     Application.Current.Dispatcher.BeginInvoke(
        System.Windows.Threading.DispatcherPriority.Normal,
        (Action)(() => txtRequest.Text = requestText));


有時候, 可能同一個 function, 有機會被 UI Thread call, 亦可能被 background thread call, 為避把 UI update 的地方都重複, 可以做一個負責 update UI 既 function, 從中檢查是否在 UI Thread, 如果是的話就直接更新, 否則就用上面的方法, 去 call 自己一次, 就會回到 UI thread 了.

檢查 是否在 UI Thread, 可以用 Dispatcher.FromThread(Thread.CurrentThread), 如果回傳 null, 就即是不在 UI Thread 了.

以下是一個簡單例子:
     
using System.Windows.Threading;
:
:
public void UpdateUI(string data) {
  if (System.Windows.Threading.Dispatcher.FromThread(Thread.CurrentThread) == null) {
      Application.Current.Dispatcher.BeginInvoke(
        System.Windows.Threading.DispatcherPriority.Normal,
        (Action)(() => UpdateUI(data)));
      return;
  } 
  // It's now in UI Thread, it can update UI directly
  :
  :
}

2) 如果只係針對某個 field 既 update, 未必需要用 Application.CurrentDispatcher, 可以用 <Control>.Dispatcher.
     this.txtRequest.Dispatcher.Invoke(
        System.Windows.Threading.DispatcherPriority.Normal,
        (Action)(() => txtRequest.Text = requestText));


補充少少, Invoke 同 BeginInvoke 既分別:
  • Invoke - synchronous call, 要行完先至會繼續落去
  • BeginInvoke - asynchronous call, 唔駛等行完就繼續落去了.

如果無需要等既, 就無謂等了, 用 BeginInvoke 可以去得快 D.

但係, 如果你要 retrieve UI 既野, 又或者D 野有先後次序, 比如想 read txtRequest.Text 既話, 當然係要等佢番左黎先行得, 就要用 Invoke 了.

JSON

JSON 咁常用, 唔記低點用都唔得.

1) System.Web.Helpers
用 Visual Studio 2015, 去 Assemblies 入面搵唔到, 連 Extension 都無.
最後去 C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Stack 5\Packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45 搵到個最新既 System.Web.Helpers.dll 自己裝番上去.

之後 using 番 System.Web.Helpers 就用得了.


using System;
using System.Web.Helpers;

namespace myDummy
{
    class Program
    {
        static void Main(string[] args)
        {
            string jsonString = "{\"name\":\"Super\"}";
            dynamic json = Json.Decode(jsonString);
            Console.WriteLine(json.name);
            json.name = "Super169";
            json.age = "Unknown";
            jsonString = Json.Encode(json);
            Console.WriteLine(jsonString);
        }
    }
}

Tuesday, March 22, 2016

Layout - Anchor

可能用慣 VB.Net 既 Windows Form, 對住個 C# 既 WPF 真係唔多熟.
一開始整 layout, 就連 Anchor 點 set 都唔知, 記低佢先.

WPF 既玩法, 同 Windows Form 真係好唔同, 個 layout 好多選擇.

比如用 Windows Form, 要 set 跟哂成個 windows 變大縮細, 只要 Control 既 Properties 入面 Layout 既 Anchor 四邊 click 哂就得.



WPF 都有番同樣既野, 不過有少少唔同, 可能多 D 選擇, 但就好似多左幾步.
最要要係 set 左 Width 同 Height 都要 Auto (click 後面個好似 X 既 icon 就得)
之後 HorizontalAligment 同 VerticalAlignment 都要 Stretch, 就要自動變大.
呢度要主意, set 左 Stretch 而上面唔 set auto, 佢會當成 center.
最下面既 Margin 就係 auto 得黎, 同四邊既距離, 同 WF 一樣, 不過上面個圖遮住左.