3

同じ文字で始まる複数の項目がある場合に、キーボードを使用してリストボックス内の項目を選択できるようにするには、プログラムで何をすべきか教えてください。たとえば、

  • 1
  • 一度
  • オレンジ

o、n、c と入力して「Once」にフォーカスしたい場合はどうすればよいですか? デフォルトの動作とは対照的に、あるアイテムから別のアイテムにジャンプする代わりに。

4

3 に答える 3

4

KeyPress イベント ハンドラーを ListBox に追加し、押されたキーを追跡します。次に、既に入力されている完全な値を ListBox 内の項目の値と比較します。一致する場合は、アイテムを選択します。

編集:

これが私が作成した解決策です。また、キーを押す間の時間を測定します。このようにして、キーを押すまでの時間が 1.5 秒を超える場合、検索文字列が空になり、最後の検索文字が再入力されます。その後は、先ほど言ったように、一致するものを見つけて、一致するものがある場合はそのアイテムを選択します。2 つのプライベート フィールドは、最後にキーが押された時刻を追跡するためのクラス レベルのフィールドであり、文字列は検索文字列を格納するためのものです。

private DateTime _lastKeyPress;
private string _searchString;

private void ListBox1KeyPress(object sender, KeyPressEventArgs e)
{
    var newDate = DateTime.Now;
    var diff = newDate - _lastKeyPress;

    if (diff.TotalSeconds >= 1.5)
        _searchString = string.Empty;
    _searchString += e.KeyChar;

    for (var i = 0; i < listBox1.Items.Count; i++)
    {
        var item = listBox1.Items[i].ToString();
        if (item.ToLower().StartsWith(_searchString))
        {
            listBox1.SelectedItem = item;
            break;
        }
    }
    _lastKeyPress = newDate;
    e.Handled = true; //REALLY IMPORTANT TO HAVE THIS
}

LinQ を使用して searchitem の一致を取得する例を次に示します。

private void ListBox1KeyPress(object sender, KeyPressEventArgs e)
{
    var newDate = DateTime.Now;
    var diff = newDate - _lastKeyPress;
    if (diff.TotalSeconds >= 1.5)
        _searchString = string.Empty;
    _searchString += e.KeyChar;

    var found = listBox1.Items.Cast<object>().Select(t => t.ToString()).Where(item => item.ToLower().StartsWith(_searchString)).FirstOrDefault();
    if(!String.IsNullOrEmpty(found))
        listBox1.SelectedItem = found;

    _lastKeyPress = newDate;
    e.Handled = true;
}

お役に立てれば!;)

編集2:

の重要なコメントに気付いたかどうかはわかりませんe.Handled。デフォルトでは、ListBox でキーを押すと、コントロールはそのキー文字で最初に見つかった項目を選択します。しかし、私のコードが持つ機能はありません。したがって、e.Handledラインをリモートにすると、コードは機能しますが、コントロールもキープレスを処理するため、それは望ましくありません。項目が正しく選択されません!

于 2012-10-17T08:23:16.927 に答える
3

LBS_SORT リスト ボックス スタイルを使用したい。このスタイルは、コントロールの作成後に適用することはできないため、このスタイルを追加するには、CreateParamsプロパティをオーバーライドする必要があります。SortedListBoxこのプロパティから派生しListBoxてオーバーライドするクラスを作成します(それを呼び出します)

public class MyListBox : ListBox
{
    protected override CreateParams CreateParams
    {
        get
        {
            var returnValue = base.CreateParams;
            returnValue.Style |= 0x2; // Add LBS_SORT
            returnValue.Style ^= 128; // Remove LBS_USETABSTOPS (optional)
            return returnValue;
        }
    }
}

このリスト ボックスは、リスト内のアイテムの並べ替えとインクリメンタル検索のサポートの両方を行う必要があります (並べ替えをオフにすることはできません。並べ替え順序を制御する必要がある場合は、インクリメンタル検索を自分で行う必要があります。アッバスのように)。提案した)

更新:さらにスタイルを削除するとLBS_USETABSTOPS、インクリメンタル検索が現在一致している文字を示す編集キャレットが表示されます

于 2012-10-17T13:14:38.337 に答える