各位老師,請教一個問題。
現在我想實作一個功能:為防止錯誤點擊,需要給一個按鈕設定權限(button2)。點擊后彈出密碼框,輸入正確密碼后可以解鎖,十分鐘之類這個按鈕正常操作。十分鐘后,該按鈕再次鎖定,必須再次輸入密碼才能操作。
我設計列一個form作為密碼框,但遇見的問題是:
命令運行后,button2依然為不可操作,顯示灰色。
另外,如何讓這個button2在十分鐘后再次為false?引入timer嗎?這代碼該如何寫呢?
請老師們指點~~
if (textBox1 .Text =="123") //輸入密碼
{
Form4 ff = new Form4(); //讓主表單的button2可以生效
ff.button2.Enabled =true;
this.Close();
}
else
{
MessageBox.Show("密碼錯誤,請重新輸入");
}
uj5u.com熱心網友回復:
設計一個系統,要把界面跟界面背后所系結的狀態(資料源)分開設計,使得“可以隨時替換不同的界面皮膚層”,這才是能做大系統的設計模式。例如可以這樣設計 VM 部分代碼public class 你的狀態 : INotifyPropertyChanged
{
public bool 是否可用
{
get
{
return DateTime.Now < 最后解鎖時間.AddMinutes(1);
}
}
string _pwd;
public string 密碼
{
get
{
return _pwd;
}
set
{
_pwd = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("密碼"));
}
}
public async Task 輸入密碼解鎖(string input)
{
if (input == 密碼)
{
最后解鎖時間 = DateTime.Now;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("是否可用"));
await Task.Delay(1000);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("是否可用"));
}
else
密碼錯誤?.Invoke(input);
}
private DateTime 最后解鎖時間 = DateTime.Now;
public event PropertyChangedEventHandler PropertyChanged;
public event Action<string> 密碼錯誤;
}
這里,VM狀態資料(資料源)有一個只讀屬性“是否可用”用來展示當前是否在輸入密碼之后1分鐘時間段之內,并且當這個屬性從“不可用”與“可用”之間切換的時候會觸發 PropertyChanged 事件通知宿主。同時還有一個“密碼”屬性用來保存、系結、事件通知用于核對的密碼。還有一個“輸入密碼解鎖”的異步操作方法,客戶程式呼叫它可以改變“可用”狀態。
設計程式,要把 View 跟 ViewModel 分開設計。例如 WPF、Knockout、Vue 等等框架都有一整套通用的機制可以將“普通資料物件、資料集合物件”與 View 上的各種現成的控制元件的屬性雙向系結,非常方便。那么關鍵就在于程式員有沒有意識、懂不懂設計理念。
一個好的程式設計師,它能夠用2、3種以上的 UI、UE 設計思路來測驗 ViewModel 狀態資料物件的設計。同一個狀態物件可以適配千變萬化的界面模板,而不改變業務邏輯代碼。只有跟一般人“相反”的做法才是工程師的做法,而不是出血則的做法。只有少數人才能成功。
uj5u.com熱心網友回復:
await Task.Delay(60000);在設計和撰寫 UI 代碼方面,現在的 .net 界面組件相關框架遠沒有 web 前端框架更貼近實戰,相當落后和麻煩了。例如將普通物件封裝為 ViewModel 物件完全可以由 Jit 編譯器代勞。這方面體現了微軟15年來沒有一個真正的面向 UI 程式開發的系統架構師而只有一幫小工匠、只會抄襲開源小專案的設計思路的尷尬。不過瘦死的駱駝比馬大,微軟必經還是有點兒貨的,還是有些最近6、7年的 .net 的新知識必須學習掌握的。
uj5u.com熱心網友回復:
密碼框觸發按鈕使能,按鈕觸發計時器使能并且更改密碼框設定,計時器觸發按鈕關閉以及恢復密碼框設定。仔細選好三個控制元件的觸發事件,然后把代碼寫上去就行了。uj5u.com熱心網友回復:
主表單bool flag = false;
private void button1_Click(object sender, EventArgs e)
{
if (!flag)
{
Form2 frm = new Form2();
frm.checkStatus += Frm_checkStatus;
frm.Show();
}
}
private void Frm_checkStatus(bool cflag)
{
flag = cflag;
thread = new Thread(changeFlag);
thread.Start();
}
Thread thread = null;
private void changeFlag()
{
while (flag)
{
Thread.Sleep(10*1000);
flag = false;
}
}
密碼輸入框
public delegate void Checkpassword(bool flag);
public event Checkpassword checkStatus;
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == "123456")
{
checkStatus(true);
}
else
{
checkStatus(false);
}
this.Close();
}
uj5u.com熱心網友回復:
我設定的是10s,你修改一下休眠時間uj5u.com熱心網友回復:
您好,可以幫忙注釋每行代碼的含義嗎?不太能理解。。。
uj5u.com熱心網友回復:
,奈何就用了一個委托一個執行緒。代碼寫的是比較隨意(#-.-)
uj5u.com熱心網友回復:
System.Threading.Timer 額 好像是這個才對uj5u.com熱心網友回復:
如果只是實作功能 不用timer 可以這樣實作第一次點擊 記錄當前時間
之后的點擊 比較記錄的時間 判斷時間差距是否大于10分鐘
兩個時間變數直接相減就能得到TimeSpan型別的變數
TimeSpan里就有時間差距的資訊
uj5u.com熱心網友回復:
你跨表單操作控制元件了,得用委托。uj5u.com熱心網友回復:
我是來學習的uj5u.com熱心網友回復:
最簡單的辦法用DialogResult 屬性主表單
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
fDialogResult dr= frm .ShowDialog();
if (dr == DialogResult.OK)
{
所有功能都可以用
button1.可否使用=false;
Sleep(10*1000); 設定休眠時間
button1.可否使用=true;
}
else
{
所有功能不可用
button1.可否使用=true;
}
}
輸入密碼表單
{
if (textBox1.Text == "123456")
{
this.DialogResult= DialogResult.OK;
this.Close();
}
else
{
this.DialogResult= DialogResult.NO;
this.Close();
}
this.Close();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/22811.html
標籤:C#
