用物件導向工具開發程式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.
沒有留言:
張貼留言