Kakeishi_Misa
@Kakeishi_Misa

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【C#】コンボボックスのスクロールした時の最終位置を取得したい

Q&A

解決したいこと

コンボボックスのスクロールの最終位置を取得したいです。

コンボボックスの値が多いため、
初めてコンボボックスをクリックした時、
表示されるまでに微妙に時間がかかります。

例えば画像のようにコンボボックスのスクロールが一番下まできたら、
21~30を追加する、といったように動的に処理がしたいです。
その後、30までスクロールすると、再び31~40を追加する、といったイベントが作成できないかと考えています。
お手数ですが、ご教示お願い致します。

キャプチャ.PNG

C#のコンボボックス

// コンボボックス初期化
foreach (int i in Enumerable.Range(1, 100))
{
    Combox.Items.Add(i);
}
0

1Answer

C#でコンボボックスといってもWindows Forms,WPF,UWPといろいろあります。
でもたぶんどれもドロップダウンのスクロール位置を取得することはできません。
(Windows FormsのコンボボックスならWndProcメソッドがあるので不可能ではないんでしょうけど…)

目的が「選択肢をすべて読み込む前にドロップダウンを表示したい」なら、スクロール位置とは関係なくドロップダウンを開いた後も非同期で項目を読み込む形が現実的でしょう。
昔試したことがあって、一応期待通りの動作にはなったけど何か問題があったような記憶が…(項目追加のたびにスクロール位置が先頭に戻るとかだったかな?)

private CancellationTokenSource cts = new CancellationTokenSource();//読み込み中止用オブジェクト

//ドロップダウン開いたイベント
private async void ComboBox_DropDown(object sender, EventArgs e)
{
    for (int i = combonox.Items.Count;; i += 10)
    {
        object[] comboboxitems = await Task.Run(ReadComboboxItems(i, 10, cts.Token));
        if (comboboxitems.Length == 0) break;
        combobox.Items.AddRange(comboboxitems);//コンボボックスへの項目追加
    }
}

//項目読み込み
private object[] ReadComboboxItems(int index, int count, CancellationToken ct)
{
    var list = new List<object>();
    for(;; index++)
    {
       object item = ReadItem(index);//index番目の項目を読み込む処理。最後まで読んでいればnullを返す
       if (ct.IsCancellationRequested)//読み込み中止指示がないかチェック
       {
           return new List<object>();//中断した場合は空の配列を返す
       }
       if (item == null)
       {
           return list.ToArray();//最後まで読み終わった
       }
       list.Add(item);
       if (list.Count >= count)
       {
           return list.ToArray();//count個を読み終わった
       }
    }
}

//ドロップダウン閉じたイベント
private async void ComboBox_DropDownClosed(object sender, EventArgs e)
{
    cts.Cancel();//読み込み中止を指示する
}

本気でスクロール位置に合わせて順次項目を読み込みたいなら、ドロップダウンリストの部分をListViewに置き換えたような独自コンボボックスを作ることになると思います。
ListViewならVirtualModeがあるので実装しやすいでしょう。

1Like

Comments

  1. @Kakeishi_Misa

    Questioner

    回答ありがとうございます。
    また、動作確認して連絡します。

Your answer might help someone💌