由于我需要禁用(灰显)ListBox中的一些项目,我使用的是可以找到here的自定义控件:
这是我目前的代码:
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
dtp.Columns.Add("key")
dtp.Columns.Add("value")
PopulateDataTable(dtp, "myTxt")
_dataView = New DataView(dtp)
'Custom ListBox
List1.ValueMember = "key"
List1.DisplayMember = "value"
List1.DataSource = _dataView
'Legacy ListBox
List2.ValueMember = "key"
List2.DisplayMember = "value"
List2.DataSource = _dataView
UpdateLanguageMenu()
End Sub
Private Function PopulateDataTable(dt As DataTable, resTxt As String)
Using sw As New StringReader(My.Resources.ResourceManager.GetObject(resTxt))
Do
Dim line As String = sw.ReadLine
If line Is Nothing OrElse line.Trim = String.Empty Then Exit Do
Dim strArr() As String
strArr = line.Split(",")
Dim row As DataRow = dt.NewRow()
row("key") = strArr(0)
row("value") = strArr(1)
dt.Rows.Add(row)
Loop
sw.Close()
End Using
End Function
List1
是自定义列表框,List2
是VS2012E附带的列表框。
我不需要List2
,它只在那里进行测试,
并且在运行时,List2
我正确地加载了所有值,而不是List1
我在所有行中得到System.Data.DataRowView
..
奇怪的是,我加载的txt就像:
00A1,MyValue1
00A2,Myvalue2
00A3,MyValue3
我还有一个Label,当我在ListBox上选择项目时,我有代码将Label.Text
更改为List.SelectedValue
,这是逗号之前的第一部分。
它会显示在标签上。仅显示自定义列表框内的项目。
手动填充List1
,而不是使用DataTable,正在使用。
由于我是初学者,我找不到问题。
答案 0 :(得分:1)
我认为你的问题与这一行有关:string displayValue = GetItemText(item);在控制中。这理所当然地认为所有项都是字符串。在你的情况下,它是一个数据视图,因此结果(drv.toString将返回类似的东西)。您需要将“item”转换为drv并将显示值设置为drvItem(“value”或“key”)。所以它基本上不是你的代码是问题,它是控件。
实际上...在读取控件中的代码而不是代码项目站点后,我意识到这一行:
displayValue = GetItemText(item);
甚至不存在。它与
交换item.ToString()
这几乎证明了我的理论。
对,如何解决。
在:
protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)
你有这个:
object item = this.Items[e.Index];
您需要做的是将项目转换为DataViewRow并将值赋给变量,如下所示:
DataViewRow dvrItem = (DataViewRow)item;
String displayText = dvrItem("key"); or String displayText = dvrItem("value");
然后改变所有这些:
e.Graphics.DrawString(item.ToString(), e.Font, SystemBrushes.GrayText, e.Bounds);
分为:
e.Graphics.DrawString(displayText, e.Font, SystemBrushes.GrayText, e.Bounds);