ListBox

タグの編集
投稿者 ugonight  (中学生) 投稿日時 2011/10/14 18:02:12
リストボックスで次のことはできますか?できるのなら方法を教えてください!
①項目が追加されたら、一番下にスクロールを自動的にする
②特定の項目の文字の色を変える

わかる方がいらっしゃったら教えてくださいorz
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/10/14 22:55:34
> 一番下にスクロールを自動的にする
VB6 なら、.TopIndex に .ListCount - 1 を代入すれば OK です。
 .TopIndex プロパティ … 最上部に表示させる項目番号
 .NewIndex プロパティ … 最後に追加された項目のインデックス
 .ListCount プロパティ … 現在の項目数

VB.NET なら、TopIndex に .Items.Count - 1 を代入すれば OK です。
 .TopIndex プロパティ … 最上部に表示させる項目番号
 .Items.Add メソッドの戻り値 … 追加した項目のインデックス
 .Items.Count プロパティ … 現在の項目数


> 特定の項目の文字の色を変える
VB6 なら、ListView で代用するのが吉。ListItem の ForeColor プロパティで着色できます。
ListBox で実装する場合は、API を利用したオーナードローという手法を使う必要があります。

VB.NET も同様に ListView を利用できます。ListViewItem の ForeColorプロパティですね。
ListBox で実装する場合は、やはりオーナードロー(自分で文字列を描画するコードを記述)が、
必要になりますが、API を使わずに実装できる分、VB6 よりは難易度は少し低いです。
http://dobon.net/vb/dotnet/control/lbownerdraw.html
投稿者 ugonight  (中学生) 投稿日時 2011/10/16 01:57:08
ありがとうございます!

①はおかげさまでできました。②は難しそうなのでまた今度…

もうひとつリストボックスについてなんですが
Dim character(10) As String
character(1) = a
character(2) = b
character(3) = c
character(4) = d
ListBox2.Items.AddRange(character)

とすると「値を Null にすることはできません。」
というエラーが出てしまいますどうしたらよいでしょうか
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/10/16 03:53:56
VB.NET をお使いなのですね?

> 「値を Null にすることはできません。」
妙ですね。そのエラーはどの行で発生していますか?

手元のVB2010 で試してみましたが、ListBox そのものは
Nothing データを問題なく受け入れるようです。
 ListBox1.Items.Add(Nothing)
 ListBox1.Items.AddRange(CType(Nothing, Object()))

となると、提示されたコードでオブジェクト参照が無いケースというと、
ListBox2 が Nothing なケースしか思い当りません。

試しに新規プロジェクトに ListBox2 を貼ってみて、その Form の Load イベントに
ugonight  さんが提示されたコードを記述した場合も、同じエラーになりますか?
投稿者 ugonight  (中学生) 投稿日時 2011/10/16 16:18:06
ありがとうございます。

うーん、やっぱり同じエラーです。
例外の詳細は
System.ArgumentNullException はハンドルされませんでした。
  Message=値を Null にすることはできません。
パラメーター名: item
  ParamName=item
  Source=System.Windows.Forms
  StackTrace:
       場所 System.Windows.Forms.ListBox.ObjectCollection.AddInternal(Object item)
       場所 System.Windows.Forms.ListBox.ObjectCollection.AddRangeInternal(ICollection items)
       場所 System.Windows.Forms.ListBox.ObjectCollection.AddRange(Object[] items)
       場所 KaosuChat.Form1.Form1_Load(Object sender, EventArgs e) 場所 C:\Users\hajime2\documents\visual studio 2010\Projects\KaosuChat\KaosuChat\Form1.vb:行 22
       場所 System.EventHandler.Invoke(Object sender, EventArgs e)
       場所 System.Windows.Forms.Form.OnLoad(EventArgs e)
       場所 System.Windows.Forms.Form.OnCreateControl()
       場所 System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       場所 System.Windows.Forms.Control.CreateControl()
       場所 System.Windows.Forms.Control.WmShowWindow(Message& m)
       場所 System.Windows.Forms.Control.WndProc(Message& m)
       場所 System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       場所 System.Windows.Forms.Form.WmShowWindow(Message& m)
       場所 System.Windows.Forms.Form.WndProc(Message& m)
       場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       場所 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       場所 System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)
       場所 System.Windows.Forms.Control.SetVisibleCore(Boolean value)
       場所 System.Windows.Forms.Form.SetVisibleCore(Boolean value)
       場所 System.Windows.Forms.Control.set_Visible(Boolean value)
       場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       場所 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       場所 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       場所 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       場所 KaosuChat.My.MyApplication.Main(String[] Args) 場所 17d14f5c-a337-4978-8281-53493378c1071.vb:行 81
       場所 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       場所 System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

となってますがよくわからないです…
投稿者 ugonight  (中学生) 投稿日時 2011/10/16 17:46:26
ちなみに
 ListBox1.Items.Add(Nothing)
 ListBox1.Items.AddRange(CType(Nothing, Object()))
もだめでした。
投稿者 YuO  (社会人) 投稿日時 2011/10/16 21:28:52
.NET Framework 4のMSDNでは,AddはArgumentNullExceptionが発生するとありますね。
MSDN: ListBox.ObjectCollection.Add メソッド (System.Windows.Forms)
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.listbox.objectcollection.add(v=VS.100).aspx
AddRangeにはないですが,同様の制約があると考えてよいでしょう。

また,こちらで追試してみましたが,.NET Framework 4CP/3.5CPどちらでもArgumentNullExceptionが発生しました。

というわけで……
Dim character(10) As String
character(1) = a
character(2) = b
character(3) = c
character(4) = d
ListBox2.Items.AddRange(character)
はそもそもcharacterを配列ではなくList(Of String)にしてAddしたものを追加するとか,
ListBox2.Items.Addで追加していく,というのが一番よいとは思いますが,
characterが外部から与えられているのであれば,
ListBox2.Items.AddRange(If(character, Enumerable.Empty(Of String)()).Where(Function (s) s IsNot Nothing).ToArray())
と,Nothingを避けてしまえばよいでしょう。
投稿者 ugonight  (中学生) 投稿日時 2011/10/16 21:58:56
ありがとうございます!無事、解決いたしました!

やっぱり、VBは何でもできるけどちょっと面倒な部分もあるんですねー
勉強になりました。