将XML元素与ListBox所选项目匹配-C#
本文关键字:项目 -C# 选项 XML 元素 ListBox | 更新日期: 2023-09-27 18:29:40
我想让它在列表框中选择的项目在标签中显示其同级元素。目前,我使用XML文件获取<Name>
元素,并用这些<Name>
值填充列表框。现在我想这样做,每当<Name>
在列表框中突出显示时,它都会在表单上的标签中显示与该模块相关的<Code>
。
即,如果在列表框中选择了算法和数据结构,则在表格上的标签中显示其代码、容量、学期和先决条件。如果选择了其他模块,则对所选模块再次执行此操作
这是我的XML:
<?xml version="1.0" encoding="utf-8" ?>
<SoftwareEngineering>
<Module>
<Name>Algorithms and Data Structures</Name>
<Code>3SFE504</Code>
<Capacity>5</Capacity>
<Semester>1</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>3D Graphics I</Name>
<Code>3SFE508</Code>
<Capacity>5</Capacity>
<Semester>1</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>Event-Driven Programming</Name>
<Code>3SFE513</Code>
<Capacity>10</Capacity>
<Semester>1</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>Object Oriented Design</Name>
<Code>3SFE514</Code>
<Capcity>10</Capcity>
<Semester>1</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>Requirements Engineering</Name>
<Code>3SFE516</Code>
<Capacity>10</Capacity>
<Semester>1</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>Introduction to AI</Name>
<Code>3SFE599</Code>
<Capacity>5</Capacity>
<Semester>1</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>Java Mobile Application Development</Name>
<Code>3SFE540</Code>
<Capacity>5</Capacity>
<Semester>1</Semester>
<Prerequisite>3SFE514(corequisite)</Prerequisite>
</Module>
<Module>
<Name>C# .NET Programming</Name>
<Code>3SFE541</Code>
<Capacity>5</Capacity>
<Semester>1</Semester>
<Prerequisite>3SFE514(corequisite)</Prerequisite>
</Module>
<Module>
<Name>Software Engineering Group Project</Name>
<Code>3SFE515</Code>
<Capacity>5</Capacity>
<Semester>2</Semester>
<Prerequisite>3SFE514(corequisite)</Prerequisite>
</Module>
<Module>
<Name>Software Engineering</Name>
<Code>3SFE519</Code>
<Capacity>10</Capacity>
<Semester>2</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>Mobile User Interface Development</Name>
<Code>3SFE542</Code>
<Capacity>5</Capacity>
<Semester>2</Semester>
<Prerequisite>3SFE540</Prerequisite>
</Module>
<Module>
<Name>Interactive Multimedia</Name>
<Code>3MTS954</Code>
<Capacity>5</Capacity>
<Semester>2</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>Concurrent Programming</Name>
<Code>3SFE555</Code>
<Capacity>5</Capacity>
<Semester>2</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>Mobile Gaming</Name>
<Code>3SFE557</Code>
<Capacity>10</Capacity>
<Semester>2</Semester>
<Prerequisite>none</Prerequisite>
</Module>
<Module>
<Name>Intelligent Systems</Name>
<Code>3SFE500</Code>
<Capacity>10</Capacity>
<Semester>2</Semester>
<Prerequisite>3SFE599</Prerequisite>
</Module>
<Module>
<Name>3D Graphics II</Name>
<Code>3SFE501</Code>
<Capacity>10</Capacity>
<Semester>2</Semester>
<Prerequisite>3SFE508</Prerequisite>
</Module>
</SoftwareEngineering>
以下是我如何努力实现我所需要的:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
XDocument doc = XDocument.Load(workingDir + @"'Moduleslist.xml");
var names = doc.Root.Descendants("Module").Elements("Code").Select(b => b.Value);
var name = doc.Root.Descendants("Module").Elements("Name").Select(a => a.Value);
if (listBox1.SelectedValue == name)
{
labelCodeNumber.Text = names.ToString();
}
}
如果有人能帮我,我会很感激
我将返回几个步骤来查看您的设计。您直接访问代码中的XML的频率是多少?每次ListBox所选索引更改时读取一个文件似乎是一种浪费,更不用说如果该文件不可访问,它会引发异常。
如果您要多次访问XML,我会考虑创建一个对象来保存您的XML数据:
public class Module
{
public String Name { get; set; }
public String Code { get; set; }
public String Capacity { get; set; }
public String Semester { get; set; }
public String Prerequisite { get; set; }
}
然后在读取XML 时创建Module对象的集合
var modules = (from elem in doc.Root.Descendants("Module")
select new Module()
{
Name = elem.Element("Name").Value,
Code = elem.Element("Code").Value,
Capacity = elem.Element("Capacity").Value,
Semester = elem.Element("Semester").Value,
Prerequisite = elem.Element("Prerequisite").Value,
}).ToDictionary(k=>k.Name,v=>v);
(如果名称元素不是唯一的,你就不能做字典,你必须做列表)
从该集合中,您可以将名称加载到listBox 中
listBox1.Items.AddRange(modules.Keys.ToArray());
然后在listBox1_SelectedIndexChanged
事件处理程序中,您可以执行以下操作:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
labelCodeNumber.Text = modules[listBox1.SelectedValue].Code;
}
您也可以考虑将Module
对象DataBinding到ListBox,但我对它不是很了解,所以我无法提供太多帮助。
编辑:以下是如何将集合放入代码中,以便您可以通过任何方法访问它。
public partial class Form1 : Form
{
private Dictionary<String, Module> modules;
public Form1()
{
this.modules = LoadXml(XDocument.Load(xmlPath);
}
private Dictionary<String, Module> LoadXml(XDocument doc)
{
return (from elem in doc.Root.Descendants("Module")
select new Module()
{
Name = elem.Element("Name").Value,
Code = elem.Element("Code").Value,
Capacity = elem.Element("Capacity").Value,
Semester = elem.Element("Semester").Value,
Prerequisite = elem.Element("Prerequisite").Value,
}).ToDictionary(k=>k.Name, v=>v);
}
}
我认为这会达到你想要的效果:
XDocument doc = XDocument.Load(Path.Combine(workingDir, @"Moduleslist.xml"));
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string name = listBox1.SelectedValue.ToString();
var propertiesFromName = (from module in doc.Root.Descendants("Module")
where module.Element("Name").Value == name
select new {Code = module.Element("Code").Value}).First();
labelCodeNumber.Text = propertiesFromName.Code;
}
这将解决您的问题,但它仍然是错误的代码。不应该每次更改索引时都读取整个文件。有关更好的解决方案,请参见下文。
替代(更好)解决方案:
创建一个具有模块所有属性的类Module
。从XML文件填充模块对象的列表,并将其设置为列表框的数据源。ListBox
有一个DisplayMember
属性,您可以将其设置为要在ListBox
中显示的属性的名称,例如"名称"。如果您这样做,那么SelectedValue
属性将是Module
的实例,您可以直接访问其属性。