我有一个列表框,其中包含来自和xml文件的标记名称,还有其他标记也存放在类中,但是当我尝试单击列表框中的值以将我的标签文本设置为value在类的内部我得到以下错误:“InvalidCastException未处理。无法将'System.String'类型的对象强制转换为'Coursework1.modules'。” 下面是代码,这是在索引发生变化时的listbox事件中。
for (int i = 0; i < selectionBox.Items.Count; i++)
{
if (selectionBox.GetSelected(i) == true)
{
infoLabel.Text = ((modules)selectionBox.Items[i]).mInfo;
lectureSlotLabel.Text = ((modules)selectionBox.Items[i]).mLSlot;
tutorialLabel.Text = ((modules)selectionBox.Items[i]).mTSlot;
prerequisiteLabel.Text = ((modules)selectionBox.Items[i]).mPreReq;
codeLabel.Text = ((modules)selectionBox.Items[i]).mCode;
nameLabel.Text =((modules)selectionBox.Items[i]).mName;
}
}
//选择框创建
String workingDir = Directory.GetCurrentDirectory();
XmlTextReader textReader = new XmlTextReader(workingDir + @"\XML.xml");
textReader.Read();
XmlNodeType type;
while (textReader.Read())
{
textReader.MoveToElement();
type = textReader.NodeType;
if (type == XmlNodeType.Element)
{
//if (textReader.Name == "Code")
//{
// module.Add(new modules(textReader.ReadElementContentAsString(),
// textReader.ReadElementContentAsString(),
// textReader.ReadElementContentAsString(),
// textReader.ReadElementContentAsString(),
// textReader.ReadElementContentAsString(),
// textReader.ReadElementContentAsString(),
// textReader.ReadElementContentAsString()));
//}
if (textReader.Name == "Code")
{
textReader.Read();
code = textReader.Value;
Console.WriteLine(code);
}
if (textReader.Name == "Name")
{
textReader.Read();
name = textReader.Value;
//selectionBox.Items.Add(name);
Console.WriteLine(name);
}
if (textReader.Name == "Semester")
{
textReader.Read();
semester = textReader.Value;
Console.WriteLine(semester);
}
if (textReader.Name == "Prerequisite")
{
textReader.Read();
preReq = textReader.Value;
Console.WriteLine(code);
}
if (textReader.Name == "LectureSlot")
{
textReader.Read();
lSlot = textReader.Value;
Console.WriteLine(lSlot);
}
if (textReader.Name == "TutorialSlot")
{
textReader.Read();
tSlot = textReader.Value;
Console.WriteLine(tSlot);
}
if (textReader.Name == "Info")
{
textReader.Read();
info = textReader.Value;
Console.WriteLine(info);
module.Add(new Modules(code, name, semester, tSlot, lSlot, info, preReq));
}
}
//Console.WriteLine(module);
}
foreach (object o in module)
{
Modules m = (Modules)o;
//String hold = m.mName;
selectionBox.Items.Add(m.mName);
}
textReader.Close();
//正在使用的标签文本
var xmlFile = XDocument.Load(xmlDirectory + @"\XML.xml");
//Finds the XML file again and looks for the Name tag
var mName = from directory in xmlFile.Descendants("Name")
where directory.Value == (String)selectionBox.SelectedItem
select directory.Parent.Element("Name").Value;
//in the mName we search the directory for the Name tag and after we search
//for the selected item of the list in the directory after that we look for
//the "Name" element in the directory and that gets the name value and saves it to
//mName
foreach (var item in mName)
{
//use the loop to make it dynamic as when the selected item changes so does,
//the moduleName label
nameLabel.Text = item.ToString();
}
答案 0 :(得分:2)
这一行:
selectionBox.Items.Add(m.mName);
只是将module
的名称改为selectionBox
,这可以解释为什么您在尝试将string
转换为module
时遇到问题。您需要了解的是使用数据绑定。添加此代码代替foreach (object o in module)
循环:
selectionBox.DataSource = module;
selectionBox.DisplayMember = "mName";
在索引更改事件中,您可以检索所选项目,如下所示:
modules m = (modules)selectionBox.SelectedItem;
此外,如果您以这种方式检索所选项目,则可以取消当前在索引更改事件处理程序中的for
循环。
修改强>
目前,您正在向module
添加每个selectionBox
的名称。但是,当您去检索所选项时,在尝试将对象的名称强制转换为实际对象时会出现错误。
所以使用我的解决方案:
selectionBox.DataSource = module;
将您创建的对象列表指定为DataSource
的{{1}}(即从中获取数据的位置),并
selectionBox
指示应将对象的哪个属性用作显示文本。在这种情况下,我有selectionBox.DisplayMember = "mName";
,因为这是您之前添加到mName
的属性。
答案 1 :(得分:-3)
这不是问题本身的答案,而是OP在评论中发布的问题的答案:
@HighCore你能告诉我你第一次演出的意思吗? 事?
你不应该做
((modules))selectionBox.Items[i]
if (selectionBox.GetSelected(i) == true)
{
var module = selectionBox.Items[i] as modules;
if (module != null)
{
infoLabel.Text = module.mInfo;
//etc...
}
}
这更简单也更安全(因为我实际上检查的是事情是modules
开始。这可以防止出现异常。