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

2 つのアプローチ:

  1. コントロールを繰り返し、表示されている場合はフォーカスを設定します
  2. TabIndex を使用し、フォーカスを最初に設定します。次に、フォーカスが最初に表示されているコントロールに落ちる必要があります
于 2010-04-08T13:54:31.650 に答える
1

クライアント側の機能であるフォーカスを設定するだけです。私は個人的にこれをjavascriptで(jQueryを使用して)行います。表示に設定されていない ASP.NET コントロールは HTML でレンダリングされないため、これらの要素の存在を探すことができます。または、最初に表示され、有効になっているコントロールを探しているだけであれば、より簡単な方法があるかもしれません。

于 2010-04-08T15:23:05.933 に答える
1

条件を満たした後に戻ることができます。たとえば、次のようになります。

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

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

等..

于 2010-04-08T13:53:33.080 に答える
1

コントロールを反復して、表示されている場合はフォーカスを設定できます。ただし、コードを読みやすくするために状態パターンを使用することをお勧めします。

于 2010-04-08T14:11:10.890 に答える
0

評価する項目のリストが大きい (場合によっては非常に大きい) 場合、次のように条件付きロジックから評価の順序を分離しようとします。

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

jumpto についてはどうですか。ここでそれを使用できるようです。

于 2010-04-08T14:08:23.220 に答える
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 に答える