C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: [C#Windowsアプリ]テキストボックス インテリセンス


(過去ログ 95 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■56795 / inTopicNo.1)  [C#Windowsアプリ]テキストボックス インテリセンス
  
□投稿者/ マサヤ (234回)-(2011/02/01(Tue) 11:14:54)

分類:[C#] 

いつも楽しく拝見させていただいております。
初めてネタふりをさせていただきます。

Windowsアプリケーションにてテキストボックスのインテリセンスっぽいものを作成してみました。
ダメ出しをお願いいたします。

デザインはtextBox1とlistBox1を配置いたします。
イベントはtextBox1_KeyDownとlistBox1_MouseDoubleClickとtextBox1_Clickになります。
以下、コードになります。

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
     if (e.KeyCode != Keys.Delete && e.KeyCode != Keys.Back)
     {
         listBox1.DataSource = null;
         string baseText = textBox1.Text.Trim();
         Keys key = e.KeyData;
         baseText += key.ToString();
         ArrayList arrChecked = arSearch(baseText);
         listBox1.Visible = true;
         listBox1.DataSource = arrChecked;
     }
}

private ArrayList arSearch(string searchString)
{
     ArrayList ar = new ArrayList();
     // DBから情報を取得したり、定数で設定したり
     string[] searched = {"aa","abb","aabbcc","aaaacccc","aaappp","aaapppll","apple","apear" };
     foreach (string search in searched)
     {
         int counter = 0;
         // 短い方に合わせる 問題ありか!?
         if(searchString.Length < search.Length)
         {
             counter = searchString.Length;
         }
         else
         {
             counter = search.Length;
         }
         string target = search.Substring(0,counter);
         string stBase = searchString.Substring(0, counter);
         if (String.Compare(target,stBase, true) == 0)
         {
              ar.Add(search);
         }
     }
     return ar; 
}

private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
      textBox1.Text = listBox1.SelectedItem.ToString();
      listBox1.Visible = false;
      textBox1.Focus();
}

private void textBox1_Click(object sender, EventArgs e)
{
      listBox1.Visible = false;
}

引用返信 編集キー/
■56796 / inTopicNo.2)  Re[1]: [C#Windowsアプリ]テキストボックス インテリセンス
□投稿者/ 魔界の仮面弁士 (2043回)-(2011/02/01(Tue) 11:48:12)
No56795 (マサヤ さん) に返信
> Windowsアプリケーションにてテキストボックスのインテリセンスっぽいものを作成してみました。

これって、MultiLine TextBox に対する語句入力ヒントなどではなく、
TextBox 全体に対する入力補完なのですよね。

であれば ListBox を使わずとも、
 string[] searched = {"aa","abb","aabbcc","aaaacccc","aaappp","aaapppll","apple","apear" };
 textBox1.AutoCompleteMode = AutoCompleteMode.Suggest; // ←ここの設定はお好みで
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
textBox1.AutoCompleteCustomSource.AddRange(searched);
だけで良い気がします。


> ArrayList ar = new ArrayList();
あえて ArrayList を使っているという事は、.NET 1.x をお使いなのでしょうか?
(上記 AutoCompleteCustomSource プロパティを使うには .NET 2.0 以降が必要です)
引用返信 編集キー/
■56797 / inTopicNo.3)  Re[1]: [C#Windowsアプリ]テキストボックス インテリセンス
□投稿者/ shu (397回)-(2011/02/01(Tue) 12:25:55)
No56795 (マサヤ さん) に返信

keydown時のテキストの選択状態とリストボックスを選択した後(または閉じた後)のカーソル位置

TextBoxから派生にした方が使いやすいのではないか?

魔界の仮面弁士さんのコメにもありますが、ArrayListは2.0以降はあまり使いたくない。

長く一致しているものをリストの上のほうに持ってきたほうがいいのではないか?

とりあえずこんなんでどうでしょう?
引用返信 編集キー/
■56798 / inTopicNo.4)  Re[1]: [C#Windowsアプリ]テキストボックス インテリセンス
□投稿者/ よねKEN (671回)-(2011/02/01(Tue) 12:45:53)
listBox1の表示場所やサイズは固定ですか?

> ダメ出しをお願いいたします。

とのことですが、どういう方向性でどのレベルまで作りたいのか?という説明がないので、
ビジュアルの制御は話題の対象の内なのか外なのかわかりません!

インテリセンスっぽいものに求める内容やレベルは人によってイメージするものが
かなり違うと思うので「どうしたいのか」を明示することは重要だと思います。
引用返信 編集キー/
■56799 / inTopicNo.5)  Re[2]: [C#Windowsアプリ]テキストボックス インテリセンス
□投稿者/ 魔界の仮面弁士 (2044回)-(2011/02/01(Tue) 12:56:18)
No56797 (shu さん) に返信
> TextBoxから派生にした方が使いやすいのではないか?
その場合、ListBox をどうするかが問題になりますね。

(案1) コンストラクタやプロパティ等で、連動する ListBox を指定可能な作りにする。
 → 現行コードに近い動作にできそう。

(案2) 入力候補が上がった時点でイベントを発生し、利用側がそれに応じて ListBox に表示させる。
 → 利用手順が若干煩雑になるものの、利用者側でのカスタマイズが可能になるというメリットも。
  (ListBox 以外への表示が可能になるなど)

(案3) TextBox 派生クラス側が、内部で独自に Form + ListBox を用意し、そこに表示させる。
 → 呼出元とは別の枠無しフォームに ListBox を表示させる事で、
  入力候補を Form の外にはみ出して表示できるようになる。

> ArrayListは2.0以降はあまり使いたくない。
2.0 以降なら、System.Collections.Generic.List<System.String> でしょうね。
1.x であれば、System.Collections.Specialized.StringCollection が使えるかも。


> 長く一致しているものをリストの上のほうに持ってきたほうがいいのではないか?
個人的には、ソートして表示して欲しいですね。
項目が多くなった場合に探しきれませんから。

あとは:

・マウス前提の設計だと入力支援としては使いにくいので、上下矢印での選択切り替えや
 キーボードからの確定なども対応した方が良いかも。

・textBox1_Click で候補を消していますが、他のコントロールにフォーカスが遷移した場合も
 消えるべきかと思うので、現在のフォーカスが textBox1/listBox1 のいずれでも無いなら
 非表示にするという作りの方が良いかも。

・KeyDown イベントで拾うだけだとキーボード入力にしか対応できません。
 実際にはスタイラスでの入力もありますし、マウス操作での削除/切り取り/貼り付けも
 行われるので、たとえば TextChanged で処理できないかなど、さらに検討が必要かも。
引用返信 編集キー/
■56801 / inTopicNo.6)  Re[2]: [C#Windowsアプリ]テキストボックス インテリセンス
□投稿者/ マサヤ (235回)-(2011/02/01(Tue) 14:27:31)
魔界の仮面弁士さん、shuさん、よねKENさん
ありがとうございます。

textBox1.AutoCompleteModeを知りませんでした orz三

>語句入力ヒントなどではなく、
>TextBox 全体に対する入力補完なのですよね。
→そのあたりの仕様は深く考えておりませんでした。

>長く一致しているものをリストの上のほうに持ってきたほうがいいのではないか?
→はい、その方がユーザビリティがいいと思います。

>魔界の仮面弁士さんのコメにもありますが、ArrayListは2.0以降はあまり使いたくない。
→一般的にArrayListってパフォーマンスよくないのでしょうか?確かによくListは使用しますが。

>listBox1の表示場所やサイズは固定ですか?
→テキストボックス直下で、サイズはノープランです。

>どういう方向性でどのレベルまで作りたいのか?という説明がないので、
>ビジュアルの制御は話題の対象の内なのか外なのかわかりません!
→ビジュアルの制御は考えてなかったです。レベル感としては単純に使いやすいもの、です。
引用返信 編集キー/
■56802 / inTopicNo.7)  Re[3]: [C#Windowsアプリ]テキストボックス インテリセンス
□投稿者/ マサヤ (236回)-(2011/02/01(Tue) 14:37:33)
魔界の仮面弁士さん
ありがとうございます。

あ、.NetFrameWorkは3.5です。

>> 長く一致しているものをリストの上のほうに持ってきたほうがいいのではないか?
>個人的には、ソートして表示して欲しいですね。
>項目が多くなった場合に探しきれませんから。
→どっちがユーザに好まれるんでしょうか。

>(案2) 入力候補が上がった時点でイベントを発生し、利用側がそれに応じて ListBox に表示させる。
> → 利用手順が若干煩雑になるものの、利用者側でのカスタマイズが可能になるというメリットも。
>  (ListBox 以外への表示が可能になるなど)
→リストの内容はユーザが追加、編集、削除できたら使いやすいだろうな、と思いましたので案2がいいかな、と思います。

>・マウス前提の設計だと入力支援としては使いにくいので、上下矢印での選択切り替えや
> キーボードからの確定なども対応した方が良いかも。
→素晴らしい!!

>・textBox1_Click で候補を消していますが、他のコントロールにフォーカスが遷移した場合も
> 消えるべきかと思うので、現在のフォーカスが textBox1/listBox1 のいずれでも無いなら
> 非表示にするという作りの方が良いかも。
→考慮漏れですね。。。完全に。。。

>・KeyDown イベントで拾うだけだとキーボード入力にしか対応できません。
> 実際にはスタイラスでの入力もありますし、マウス操作での削除/切り取り/貼り付けも
> 行われるので、たとえば TextChanged で処理できないかなど、さらに検討が必要かも。
→確かにgoogle先生もyahooさんも対応してますね。これはやらないといけないです。
引用返信 編集キー/
■56803 / inTopicNo.8)  Re[3]: [C#Windowsアプリ]テキストボックス インテリセンス
□投稿者/ shu (398回)-(2011/02/01(Tue) 14:55:41)
No56801 (マサヤ さん) に返信

> >魔界の仮面弁士さんのコメにもありますが、ArrayListは2.0以降はあまり使いたくない。
> →一般的にArrayListってパフォーマンスよくないのでしょうか?確かによくListは使用しますが。

MSDNより
http://msdn.microsoft.com/ja-jp/library/6sh2ey19.aspx
ArrayListの利点(?)は500要素以下の値型の場合にボックス化で利用されるメモリ量がジェネリックにより
生成された実装より小さくて済むということのようです。それだけです。ボックス化自体はパフォーマンスが
よくないのでその程度なら使わないほうがいいかと思います。また型が決まっているため型推論が
使えることがすごく便利だと思っています。







引用返信 編集キー/
■56809 / inTopicNo.9)  Re[4]: [C#Windowsアプリ]テキストボックス インテリセンス
□投稿者/ マサヤ (237回)-(2011/02/01(Tue) 15:16:56)
2011/02/01(Tue) 15:17:36 編集(投稿者)

shuさん
ありがとうございます。

No56803 (shu さん) に返信
> ■No56801 (マサヤ さん) に返信
>
>>>魔界の仮面弁士さんのコメにもありますが、ArrayListは2.0以降はあまり使いたくない。
>>→一般的にArrayListってパフォーマンスよくないのでしょうか?確かによくListは使用しますが。
>
> MSDNより
> http://msdn.microsoft.com/ja-jp/library/6sh2ey19.aspx
> ArrayListの利点(?)は500要素以下の値型の場合にボックス化で利用されるメモリ量がジェネリックにより
> 生成された実装より小さくて済むということのようです。それだけです。ボックス化自体はパフォーマンスが
> よくないのでその程度なら使わないほうがいいかと思います。また型が決まっているため型推論が
> 使えることがすごく便利だと思っています。
→確かにIList<型>は型がはっきりしているのは自分も使い勝手がいいと思います。
単純な配列だしArrayListでいいか、と深く考えずに使ってましたが、パフォーマンスに関する考慮事項を読むと興味深いですね。
リストの要素が500超えるなどの境界値は全く考慮しておりませんでした。

ありがとうございます。
勉強になります。
引用返信 編集キー/
■56811 / inTopicNo.10)  Re[4]: [C#Windowsアプリ]テキストボックス インテリセンス
□投稿者/ 魔界の仮面弁士 (2046回)-(2011/02/01(Tue) 15:42:39)
2011/02/01(Tue) 15:45:01 編集(投稿者)

No56801 (マサヤ さん) および
No56802 (マサヤ さん) に返信
> textBox1.AutoCompleteModeを知りませんでした orz三

ちなみに .NET 1.x で同様の機能を呼び出す場合は SHAutoComplete API を呼び出すか、
または IAutoComplete / IAutoComplete2 に IEnumString を渡すという実装方法になります。

この IEnumString インターフェイスは、System.Runtime.InteropServices.UCOMIEnumString
(2.0 以降は System.Runtime.InteropServices.ComTypes.IEnumString )に用意されています。

IAutoComplete は、Type.GetTypeFromCLSID(new Guid("{00BB2763-6A77-11D0-A535-00C04FD7D062}")) で。


>> あとは:
該当する候補が 0 件だった場合に、空の ListBox を表示すべきか否か、とか。


>>> 長く一致しているものをリストの上のほうに持ってきたほうがいいのではないか?
>> 個人的には、ソートして表示して欲しいですね。
>> 項目が多くなった場合に探しきれませんから。
> →どっちがユーザに好まれるんでしょうか。
URL やファイルシステムを表示する場合には、ソートされてないと困ると思いますが、
細かい点は、利用者側でカスタマイズ可能な仕組みにしておくのも選択肢のひとつです。

今回の実装では、先頭一致する物だけに絞り込まれて表示されていますが、
VBA のインテリセンスや Microsoft SmallBasic のように、
入力候補を絞り込むことはせずに、一覧の中でもっとも近い語句に
フォーカスを当てておく(ただし未選択)という実装方法もありますね。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -