Как уменьшить эту лестницу IF-Else в c # - PullRequest
5 голосов
/ 08 апреля 2010

Это лестница 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 приведет к снижению производительности, поскольку мне придется пересекать всю коллекцию страниц. Я глубоко на странице, которая имеет шедевры. Пожалуйста, предложите.

Ответы [ 10 ]

8 голосов
/ 08 апреля 2010

Я думаю, твое дерево хорошо. Это, безусловно, выглядит как логическое дерево, которое можно упростить, и у вас есть хорошее обоняние, чтобы с подозрением относиться к нему. Однако, похоже, что логическое дерево отражает то, что вам нужно. Логика на самом деле является такой запутанной , и это условная структура, которую C # дает вам для решения этой ситуации. Я не думаю, что это может быть улучшено.

Если у вас был простой список элементов управления, который должен иметь фокус, и вы хотели выделить первый элемент управления в списке, вы могли бы сделать это:

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

Но, похоже, у вас есть некоторые дополнительные критерии, так что это не сработает.

3 голосов
/ 08 апреля 2010

Если вы просто пытаетесь сфокусировать первый видимый элемент управления на форме, я бы заменил всю лестницу одним циклом:

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;
        }
    }
}
3 голосов
/ 08 апреля 2010

Два подхода:

  1. Перебор элементов управления и установка фокуса, если они видимы
  2. Используйте TabIndex и установите фокус в первую очередь. Тогда фокус должен упасть до первого видимого контроля
1 голос
/ 08 апреля 2010

Все, что вы делаете, это устанавливаете фокус, который является функциональностью на стороне клиента. Я лично сделал бы это в javascript (используя jQuery). Элементы управления ASP.NET, для которых не задано значение «видимый», не отображаются в HTML, поэтому вы можете посмотреть на наличие этих элементов, или может быть более простой способ, если вы просто ищете первый видимый, включенный элемент управления.

1 голос
/ 08 апреля 2010

Вы можете перебирать элементы управления и устанавливать фокус, если они видны. Но я бы посоветовал вам использовать шаблон состояний для лучшей читаемости кода.

1 голос
/ 08 апреля 2010

Вы можете вернуться после того, как соответствуете вашим критериям, например:

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

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

и т.д ..

0 голосов
/ 09 апреля 2010

Вот немного другой взгляд на проблему. Во-первых, определите интерфейс для представления элементов управления, которые могут или не могут быть сфокусированы:

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() при необходимости.

0 голосов
/ 09 апреля 2010

Это классический конечный автомат. Настроив машину, она может облегчить понимание и поддержку кода, , хотя может добавить к общим строкам .

Я не буду вдаваться в специфику вашего кода, но обнажусь со мной. Определив, в каком состоянии работает пользователь, вы можете программно изменить различные значения в понятном для конкретного состояния состоянии 1006 *. (Псевдокод ниже)

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. HTH

}

0 голосов
/ 08 апреля 2010

Когда список элементов для оценки большой (а иногда он очень большой), я пытаюсь отделить порядок оценки от условной логики, что-то вроде этого:

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();
}
0 голосов
/ 08 апреля 2010

Что касается прыжка, кажется, вы могли бы использовать это здесь.

...