顯示具有 Winform 標籤的文章。 顯示所有文章
顯示具有 Winform 標籤的文章。 顯示所有文章

2.16.2021

.Net Desktop Skeleton

.Net Desktop UI Skeleton Project

Recently I created two skeleton project for c# desktop environment,

Prism is WPF only, but ReactiveUI can use with WPF and WinForm.

The prism skeleton is based on prism template pack, but I upgrade the prism version to v8.0.

Prism Shell

ReactiveUI Shell

How To Start

Cloning the repository, either Prism or ReactiveUI

  1. Clone this repository:
    1. Prism: git clone https://github.com/liaochihung/PrismBlankApp.git your-project-name
    2. ReactiveUI git clone https://github.com/liaochihung/ReactiveUIBlankApp.git your-project-name
  2. Move to the project directory: cd your-project-name
  3. Create your own repository and cleaning the bootstrap project history:
    1. Remove previous Git history in order to do not add the bootstrap repo noise in your project: rm -rf .git
    2. Initialize your own Git repository: git init
    3. Add the bootstrap files: git add .
    4. Commit
    5. Add your remote repository: git remote add origin git@github.com:your-name/your-project-name
    6. Upload your local commits to the new remote repo: git push -u origin master
  4. Start coding!

Written with StackEdit.

11.24.2016

WinForm表單控制項狀態管理 - MVVM(with ReactiveUI) way

用物件導向工具開發程式1

最早最早,所有code都寫在Form中時,狀態的變更,落在各個被觸發的事件中,假設目前我們有一個TextBox,一個Button,程式需求TextBox中至少要n個字元才可以觸發Button的Click事件,於是我們在TextBox的TextChanged事件中加上判斷,再設定按鈕Enabled,搞定。

但事情發生在多個控制項,多個狀態時,複雜度隨之而來。

開發物件導向程式

於是,換個方向,使用狀態Property,在它的setter中寫判斷邏輯,看起來很好,但還是跟Form綁太緊了。尋找進階版,Mediator浮現,嗯嗯,符合SRP原則,可是好像不夠OCP,沒關係,再抽象一次…
發現有人寫好了(UI State Synchronization of WinForm Controls)

_stateManager
    .AddCommand(CMD_INDEX_CHECKING, UIObject.CreateObject(this.btnRemTarget));
_stateManager
    .AddCommand(CMD_INDEX_CHECKING, UIObject.CreateObject(this.btnSpiralTest));
_stateManager
    .AddCommand(CMD_INDEX_CHECKING, UIObject.CreateObject(this.btnIndexCheck));

_stateManager
    .AddCommand(CMD_SPIRAL_CHECKING, UIObject.CreateObject(this.btnRemTarget));
_stateManager
    .AddCommand(CMD_SPIRAL_CHECKING, UIObject.CreateObject(this.btnSpiralTest));
_stateManager
    .AddCommand(CMD_SPIRAL_CHECKING, UIObject.CreateObject(this.btnIndexCheck));

UI層的狀態維護,交給Mediator負責,而這個可重用的Mediator中透過字典記錄使用者定義的命令及相對應的控制項,並依需要設定控制項的狀態,這種方式下再配合Model-View-Presenter模式,UI和Presenter不再耦合,Presenter中也不用再出現WinForm相關的參考,perfect!

那…為什麼要ReactiveUI?

因為它支援.Net目前大多數的Presentation,in MVVM way.
GitHub測試

View

var context = SynchronizationContext.Current;
VM = new ViewModel2(
    context,
    this.WhenAnyValue(x => x.textBox1.Text),
    this.WhenAnyValue(x => x.textBox2.Text)));

// bind ViewModel's property to control
this.Bind(VM, x => x.UserName, x => x.textBox1.Text);
this.Bind(VM, x => x.Password, x => x.textBox2.Text);

// extra bind, let a property in ViewModel determinate the state of a control
VM.CanUserLogin.BindTo(this, x => x.btnLogin.Visible);

ReactiveUI提供了一個額外的綁定功能,如上將CanUserLogin綁定至控制項的屬性中。而其它的Bind動作,若是在xaml系的表單上,可以直接指定。

ViewModel, 實作商業邏輯

name.ToProperty(this, x => x.UserName, out _userName);
password.ToProperty(this, x => x.Password, out _password);

CanUserLogin = this.WhenAnyValue(
    x => x.UserName, x => x.Password,
    (user, pass) =>
        !string.IsNullOrWhiteSpace(user) &&
        !string.IsNullOrWhiteSpace(pass) &&
        user.Length >= 2 && pass.Length >= 3)
    .DistinctUntilChanged();

Written with StackEdit.