自分のブログ名

sheephumanのブログ

広汎性発達障害と診断されたASD孤立型。

【C#】ListBox内の全ての項目を検索して描画する

 

 

ひつじ!人間です。まさにひつじ。

未だにWinFormから卒業出来ない僕。サポート終了したら産廃になるよなあコレ。

 

今回は以下のページのコードを参考に一部を改変しました。

 

 

hanatyan.sakura.ne.jp

 

これはVBなんですが、VBからC#への翻訳ってなれると割と簡単なのでやってしまってます。再帰で検索するのですが、位置情報を更新してやらないといけないですね。

 

 

 

 

これも参考にした。

blog.livedoor.jp

 

 

結果

C# ListBox内の全ての項目を検索する



 

コード全文(一部改変)


using System;
using System.Drawing;
using System.Windows.Forms;

namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            listBox1.Items.Add("たちつてと");
            listBox1.Items.Add("たちつてと");
            listBox1.Items.Add("あいうえお");
            listBox1.Items.Add("かきくけこ");
            listBox1.Items.Add("さしすせそ");
            listBox1.Items.Add("たちつ");
            listBox1.Items.Add("なにぬねの");
            listBox1.Items.Add("なにぬねの");
            listBox1.Items.Add("たちつてと");
            listBox1.Items.Add("はひふへほ");
            listBox1.Items.Add("まみむめも");
            listBox1.Items.Add("たちつ");
            listBox1.Items.Add("たちつてと");


        }

        private void button1_Click(object sender, EventArgs e)
        {
            //"たちつ"を前方一致検索(すべての項目を検索)

            ListBoxSearch(listBox1, "たちつ", 0);
        }

        private void ListBoxSearch(ListBox listBox, string searchSt, int startPos)
        {
            int ret = listBox.FindString(searchSt, startPos);


            if (ret < startPos || ret == -1) //見つからなかった場合
            {
                return;
            }
            else
            {
                //b = new SolidBrush(Color.Green);
                listBox.SetSelected(ret, true);


                if (ret < listBox.Items.Count - 1)  //次を検索
                {
                    startPos = ret;

                    listBox.SelectionMode = SelectionMode.MultiExtended;
                    listBox.SetSelected(ret, true);
                    ListBoxSearch(listBox, searchSt, startPos);
                }
                else { return; }
            }


        }


        private void ListBoxSearch(ListBox listBox, string searchSt, int startPos, DrawItemEventArgs e)
        {
            Brush b = null;
            int ret = listBox.FindString(searchSt, startPos);


            if (ret < startPos || ret == -1) //見つからなかった場合
            {
                return;
            }
            else  //見つかった場合
            {

                if (ret < listBox.Items.Count - 1)  //次を検索
                {
                    startPos = ret; //開始位置の更新

                    string txt = "";
                    //描画する文字列の取得
                    if (listBox.Items[e.Index].ToString().Contains(searchSt))
                    { txt = listBox.Items[e.Index].ToString(); }

                    b = new SolidBrush(Color.White);

                    if (b != null && txt != "")
                    {
                        e.DrawBackground();
                        e = new DrawItemEventArgs(e.Graphics, e.Font, e.Bounds, e.Index, e.State, e.ForeColor, Color.Green);
                        e.Graphics.DrawString(txt, e.Font, b, e.Bounds);

                        //後始末
                        b.Dispose();
                    }


                    ListBoxSearch(listBox, searchSt, startPos, e);
                }

                else { return; }
            }





        }

        private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
        {

          
            //ListBoxSearch(listBox1,"たちつ",-1,e);
            //背景を描画する
            //項目が選択されている時は強調表示される
            

            //ListBoxが空のときにListBoxが選択されるとe.Indexが-1になる
            if (e.Index > -1)
            {
                //文字を描画する色の選択
                Brush b = null;
                if ((e.State & DrawItemState.Selected) != DrawItemState.Selected)
                {

                    b = new SolidBrush(Color.Black);
                 
                }
                else
                {
                    //選択されている時はそのままの前景色を使う
                    b = new SolidBrush(Color.White);

                  
                }
                //描画する文字列の取得
                string txt = ((ListBox)sender).Items[e.Index].ToString();

                if (b != null)
                {   //文字列の描画
                    e.DrawBackground();
                     
                    e.Graphics.DrawString(txt, e.Font, b, e.Bounds);
                    //後始末
                    b.Dispose();
                }


            }

            //フォーカスを示す四角形を描画
            //e.DrawFocusRectangle();

            ListBoxSearch(listBox1, "たちつ", -1, e);

        }
    }
}

あとがき

とりあえずこんな感じで。かなり手こずった方ですね。
糸口が速めに見つかったのが良かったです。一から書いてると3倍以上の時間掛かったりするんで、流用はやはり楽でいいです。 家計簿アプリにも実装します。