5

这是我创建的 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 会占用性能,因为我必须遍历整个页面集合。我对有母版页的页面很感兴趣。请提出建议。

4

10 回答 10

8

我觉得你的树很好。这当然看起来像一棵可以简化的逻辑树,你有很好的嗅觉去怀疑它。但是,逻辑树似乎反映了您的需求。逻辑真的很复杂,这是 C# 为您提供处理这种情况的条件框架。我不认为它可以改进。

如果您有一个应该具有焦点的简单控件列表,并且您想将焦点放在列表中的第一个可见控件上,您可以这样做:

(From c in ListOfControls
Where c.visible = true
Select c).First.Focus();

但是,您似乎有一些额外的标准,所以这行不通。

于 2010-04-08T13:53:39.403 回答
3

如果您只是想将第一个可见控件集中在表单上,​​那么我会用一个循环替换整个梯子:

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;
        }
    }
}
于 2010-04-08T13:56:21.040 回答
3

两种方法:

  1. 迭代控件并设置焦点(如果可见)
  2. 使用 TabIndex 并将焦点设置为 first。然后焦点应该落在第一个可见控件上
于 2010-04-08T13:54:31.650 回答
1

您可以在满足条件后返回,例如:

   if (ddlTranscriptionMethod.Visible) 
    { 
        ddlTranscriptionMethod.Focus(); 
        return;
    }

    if (ddlSpeechRecognition.Visible) 
    { 
        ddlSpeechRecognition.Focus(); 
        return;
    } 

ETC..

于 2010-04-08T13:53:33.080 回答
1

您可以迭代控件并设置焦点(如果可见)。但我建议您使用状态模式以获得更好的代码可读性。

于 2010-04-08T14:11:10.890 回答
1

您所做的一切就是设置焦点,即客户端功能。我会亲自在 javascript 中执行此操作(使用 jQuery)。未设置为可见的 ASP.NET 控件不会在 HTML 中呈现,因此您可以查找这些元素的存在,或者如果您只是查找第一个可见的启用控件,则可能有更简单的方法。

于 2010-04-08T15:23:05.933 回答
0

jumpto 怎么样,你可以在这里使用它。

于 2010-04-08T14:08:23.220 回答
0

When the list of items to evaluate is large (and sometimes it's very large), I try to separate the order of evaluation from the conditional logic, something like this:

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();
}
于 2010-04-08T17:58:08.113 回答
0

这是一个经典的状态机。通过设置一台机器,它可以使代码更易于理解和维护,尽管它可能会增加总行数

我不会详细介绍您的代码。通过确定用户正在操作的状态,您可以以可理解的特定状态方式以编程方式更改不同的值。(下面的伪代码)

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。

于 2010-04-09T15:49:11.517 回答
0

这是对这个问题的稍微不同的看法。首先,定义一个接口来表示可能会或可能不会被聚焦的控件:

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()在必要时调用。

于 2010-04-09T17:10:20.673 回答