From 心靈魔術師s blog
在設備操作面板的設計中總會有一類固定的按鈕和操作慣例,但如果每做一個項目都寫一套同樣的代碼實在很沒效率的事。
設備的操作按鈕大多數都會包含啟動、暫停、停止這三個按鈕,軟件界面中也同樣需要這三類按鈕,軟件需要根據設備的狀態
來禁用或啟用不同的按鈕組合。比如剛啟動軟件時,啟動按鈕開啟,暫停和停止按鈕禁用等等。
一般設計情況下是用Button,也有的設計會用ToolStripButton,為了使其兼容更多的控件,所以采用了泛型。代碼如下:
public enum OperateState { Run, Pause, Stop };
public class OperateStateRule<T> where T : ToolStripItem
{
private T start;
private T pause;
private T stop;
private OperateState state = OperateState.Stop;
private OperateState State
{
get { return state; }
//set { state = value; }
}
public OperateStateRule(T _start, T _pause, T _stop)
{
start = _start;
pause = _pause;
stop = _stop;
Update(OperateState.Stop);
}
public void Update(OperateState _state)
{
state = _state;
try
{
switch (state)
{
case OperateState.Stop:
start.Enabled = true;
pause.Enabled = false;
stop.Enabled = false;
break;
case OperateState.Run:
start.Enabled = false;
pause.Enabled = true;
stop.Enabled = true;
break;
case OperateState.Pause:
start.Enabled = true;
pause.Enabled = false;
stop.Enabled = true);
break;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
調用示例:
ToolStripButton btnStart;
ToolStripButton btnPause;
ToolStripButton btnStop;
//生成對象時綁定相應的按鈕
OperateStateRule<ToolStripButton> rule = new OperateStateRule<ToolStripButton>(btnStart,btnPause,btnStop);
//在Click事件裡更新狀態
private void btnStart_Click(object sender, EventArgs e)
{
rule.Update(OperateState.Run);
}
private void btnPause_Click(object sender, EventArgs e)
{
rule.Update(OperateState.Pause);
}
private void btnStop_Click(object sender, EventArgs e)
{
rule.Update(OperateState.Stop);
}
在類聲明上有個where T : ToolStripItem語句,這個是c#類型約束,如果不加這個約束,編譯器會報錯找不到Enabled屬性,
但有個問題Button和ToolStripButton這兩個類不是同一個基類派生,所以無法兼容使用這2個類,因為必須要有這個約束,使得c++
的一些泛型做法受到限制。
那還有沒有更好的方法來達到理想的效果呢,答案是有的,就是反射。看下面改進的代碼例子:
public enum OperateState { Run, Pause, Stop };
public class OperateStateRule<T>
{
private T start;
private T pause;
private T stop;
private OperateState state = OperateState.Stop;
private OperateState State
{
get { return state; }
//set {