[英]How to reduce this IF-Else ladder in c#
這是我創建的IF -Else梯形圖,用於將第一個可視控件集中在我的窗體上。根據要求,任何控件都可以隱藏在窗體上。所以我必須找到第一個可見的控件並將其聚焦。
if (ddlTranscriptionMethod.Visible)
{
ddlTranscriptionMethod.Focus();
}
else if (ddlSpeechRecognition.Visible)
{
ddlSpeechRecognition.Focus();
}
else if (!SliderControl1.SliderDisable)
{
SliderControl1.Focus();
}
else if (ddlESignature.Visible)
{
ddlESignature.Focus();
}
else
{
if (tblDistributionMethods.Visible)
{
if (chkViaFax.Visible)
{
chkViaFax.Focus();
}
else if (chkViaInterface.Visible)
{
chkViaInterface.Focus();
}
else if (chkViaPrint.Visible)
{
chkViaPrint.Focus();
}
else
{
chkViaSelfService.Focus();
}
}
}
有沒有其他方法可以做到這一點。 我認為使用LINQ會占用性能,因為我必須遍歷整個頁面集合。 我在頁面很深,有主頁。請建議。
我覺得你的樹很好。 這當然看起來像一個可以簡化的邏輯樹,你有一個良好的嗅覺懷疑它。 但是,似乎邏輯樹反映了您的需求。 這個邏輯確實很復雜 ,這是C#為您提供處理這種情況的條件框架。 我不認為它可以改進。
如果您有一個應該具有焦點的簡單控件列表,並且您希望將焦點放在列表中的第一個可見控件上,則可以執行以下操作:
(From c in ListOfControls
Where c.visible = true
Select c).First.Focus();
但是,看起來你有一些額外的標准,所以這是行不通的。
兩種方法:
如果您只是嘗試將第一個可見控件聚焦在窗體上,那么我將用一個循環替換整個梯形圖:
foreach (Control c in Controls)
{
if (c.Visible)
{
c.Focus();
break;
}
}
如果需要聚焦內部控件,請使用遞歸方法:
bool FocusFirst(ControlCollection controls)
{
foreach (Control c in controls)
{
if (c.Visible)
{
c.Focus();
FocusFirst(c.Controls);
break;
}
}
}
您可以在符合標准后返回,例如:
if (ddlTranscriptionMethod.Visible)
{
ddlTranscriptionMethod.Focus();
return;
}
if (ddlSpeechRecognition.Visible)
{
ddlSpeechRecognition.Focus();
return;
}
等等..
您可以迭代控件並設置焦點(如果可見)。 但我建議您使用狀態模式以獲得更好的代碼可讀性。
您所做的就是設置焦點,即客戶端功能。 我個人會在javascript(使用jQuery)中這樣做。 未設置為可見的ASP.NET控件不會在HTML中呈現,因此您可以查找這些元素的存在,或者如果您只是在尋找第一個可見的啟用控件,則可能會有更簡單的方法。
怎么樣跳轉似乎你可以在這里使用它。
當要評估的項目列表很大(有時它非常大)時,我嘗試將評估順序與條件邏輯分開,如下所示:
List<WebControl> wcBasics = new List<WebControl>();
wcBasics.Add(ddlTranscriptionMethod);
wcBasics.Add(ddlSpeechRecognition);
wcBasics.Add(ddlESignature);
List<CheckBox> checks = new List<CheckBox>();
checks.Add(chkViaFax);
checks.Add(chkViaInterface);
checks.Add(chkViaPrint);
private void Focus()
{
foreach (WebControl c in wcBasics)
if (c.Visible) {
c.Focus();
return;
}
if (!tblDistributionMethods.Visible) return;
foreach (CheckBox chk in checks)
if (chk.Visible) {
chk.Focus();
return;
}
}
chkViaSelfService.Focus();
}
這是一款經典的狀態機。 通過設置機器,它可以使代碼更容易理解和維護, 盡管它可能會增加總線數 。
我不會詳細介紹您的代碼。 通過確定用戶正在操作的狀態,您可以以可理解的特定狀態方式以編程方式更改不同的值。 (下面的偽代碼)
enum FormStates
{
Initial_View
Working_View
Edit_View
Shutdown_View
};
{ // Somewhere in code
switch (theCurrentState)
{
case Initial_View :
Control1.Enabled = true;
Control2.Enabled = true;
theCurrentState = Working_View;
break;
case Working_View
if (string.empty(Contro1.Text) == false)
{
Control2.Enabled = false;
Speachcontrol.Focus();
theCurrentState = Edit_view;
}
else // Control 2 is operational
{
Control1.Enabled = false;
SliderControl.Focus();
}
case Edit_View:
...
break;
break;
}
通過按邏輯步驟組織代碼,可以更輕松地添加更多狀態,而不會危及巨大的if / else。
這是對問題略有不同的看法。 首先,定義一個接口來表示可能會或可能不會聚焦的控件:
public interface IFormControl
{
bool Focus();
}
然后創建一個處理簡單案例的實現:
public class FormControl : IFormControl
{
private readonly Control _control;
public FormControl(Control control)
{
_control = control;
}
public bool Focus()
{
if(_control.Visible)
{
_control.Focus();
}
return _control.Visible;
}
}
並創建另一個處理更困難的案例:
public class DependentFormControl : IFormControl
{
private readonly Control _control;
private readonly Func<bool> _prerequisite;
public DependentFormControl(Control control, Func<bool> prerequisite)
{
_control = control;
_prerequisite = prerequisite;
}
public bool Focus()
{
var focused = _prerequisite() && _control.Visible;
if(focused)
{
_control.Focus();
}
return focused;
}
}
然后,創建一個擴展方法,將焦點設置在序列中的第一個控件上:
public static void FocusFirst(this IEnumerable<IFormControl> formControls)
{
var focused = false;
foreach(var formControl in formControls)
{
if(formControl.Focus())
{
break;
}
}
}
最后,創建要集中的控件集:
var controls = new FormControl[]
{
new FormControl(ddlTranscriptionMethod),
new FormControl(ddlSpeechRecognition),
new DependentFormControl(SliderControl1, () => !SliderControl1.SliderDisable),
new FormControl(ddlESignature),
new DependentFormControl(chkViaFax, () => tblDistributionMethods.Visible),
new DependentFormControl(chkViaInterface, () => tblDistributionMethods.Visible),
new DependentFormControl(chkViaPrint, () => tblDistributionMethods.Visible),
new DependentFormControl(chkViaSelfService, () => tblDistributionMethods.Visible)
};
controls.FocusFirst();
您可以在頁面加載時創建控件集,並在必要時調用.FocusFirst()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.