Thursday, August 25, 2016

Callback function

假設準備由 A 跳去 B, 而 B  去到某個情況下, 要 番去 執行 A 既野.

1) 如果 B 係一個 UserControl, 嚴格黎講, 唔算係 call back.  可以用 event 攪掂.

    (a) 在 B 設定一個  event
            public event EventHandler EventName>;

        By default,  個 event 既 parameter 係 EventArgs, 如果想用其他 type, 可以設定
            public event EventHandler<string>  EventName;

       咁樣, 個 event 就會有個 string type 既 parameter

    (b)  當 B 雖要 通知 A 時, 就可以 check 下個 Event 有無設定 handler, 有就 call.

       例如用番 default 既, 而你又無 parameter 要 pass, 可以咁 call:

          if (EventName != null) EventName(this, EventArgs.Empty);

    (c) 而 A 當然要在 B 既 event 設定一個 handler 比佢, 而設定既方法同其他 event 無分別.


2) 如果 B 係一個 Window, 就真係可以用 call back function 了.

    (a) 首先, 在 B 設定一個預備 call back 既 function signature, 再 設定一個 variable

             public delegate void DelActionHandler(string data);
             public event DelActionHandler actionHandler;
           
    (b) 當 B 雖要 通知 A 時, 就可以 check 下個 Event 有無設定 handler, 有就 call.

           if (actionHandler != null) actionHandler("data");

    (c) 而 A 當然要先設定一個配合 DelActionHandler 既 function, 然後就將佢加入去

          B.actionHandler += new DelActionHandler(this.action);

          private void action(string data) {...}        

 

Tuesday, May 17, 2016

WPF Single Instance

Methods to detect if another instant is running

1) Check process with same process name

2) Use Mutex

Wednesday, May 11, 2016

建位 DynamicJsonArray 既 笨法

唔知係咪好方法, 但係一直都搵唔到網上有教學.

研究過程
(1) 搵唔到 DynamicJsonArray 既 constructor 可以點樣起個吉既 array 開始玩
(2) 選擇直接用 object[] 經 DynamicJsonArray 既 constructor 直接先成完整既 DynamicJsonArray
(3) object[] 又唔係次次都一早知有幾多條 record, 簡單起見, 先做一個 List<object> 再轉 object[]

最後選擇先成 DynamicJsonArray 既方法:
(1) 如果 係簡單既 array 例如 byte[], 可以唔駛攪咁多野, 直接 assign 比個 Json object,


 
(2) 如果係其他 data type, 想辦法先變成一個 json object, 放入一個 List<objec>, 再轉:

以上兩個方法, 做完之後, json.data 就係儲住左一個 DynamicJsonArray 了.
之後就可以用 Json.Encode(json) 轉成 json string 去儲存入其他地方了.

 要讀番出黎, 先用 Json.Decode 將個 json string 變番 json, 然後.

 (1) 用 Array.ConvertAll 轉番

(2)

Sunday, May 1, 2016

Application Exit Script

如果有D野, 係想個 app 正常 exit 既時間會行既, 就可以加入 application exit script 了.
不過, 點先算係正常 exit 呢....理論上唔係中途 error 死左, 又或者比人直接 kill 既都得.


  1. 在 App.xaml 加入 Exit="<method>", 例如叫 "ApplicationExit" ....
  • 又或者開左之後, click 落 application, 在 Properties 既 Event Handler 果版,打個名都得.

  1. 之後, 在 Event Handler 果度, click 個 Exit event 既 script, 就會打開 App.xaml.cs 比你加 code 了.

想加乜就自己決定了.

Tuesday, April 26, 2016

管理員權限

有部份 Windows 提供的功能, 是需要程式獲得管理員權限才可以執行的.
例如要進行 網絡上的 Socket sniffing, 就需要有 管理員權限 了.

在程式中, 需要加上以下的處理, 就會在執行時, UAC 會向用家徵求取得 管理員權限.


  1. 新增一個 app.manifest 的檔
    在 project 上, add -> new item, 再選 "Application Manifest File"


  1. 按下 [Add] 之後, 在你的 project 中會多了一個 app.manifest 的檔.
    打開 app.新增一個 app.manifest 的檔, 會看到有關的介紹

  1. 首先把 requestdExecutionLevel 中的 level 由 "asInvoker" 改成 "requireAdministrator"
  2. 再加上以下幾句在 <security> 完結之前:

  1. 修改後的 app.manifest 將會是這樣:

Tuesday, April 12, 2016

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 一樣, 不過上面個圖遮住左.