Соответствие элементов XML выбранному элементу ListBox - C # - PullRequest
1 голос
/ 31 марта 2012

Я хочу сделать так, чтобы элемент, который я выбрал в списке, отображал элементы одного уровня в метках. В настоящее время я использовал свой 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();
            }

        }

Пожалуйста, если кто-то может мне помочь, я был бы признателен

Ответы [ 2 ]

4 голосов
/ 31 марта 2012

Я бы вернулся на пару шагов назад и посмотрел бы на ваш дизайн.Как часто вы будете обращаться к 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

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);

(если имя элемента выигралоне быть уникальным, вы не можете сделать словарь, и вам придется составить список)

Из этой коллекции вы можете загрузить имена в списокBox

listBox1.Items.AddRange(modules.Keys.ToArray());

Изатем в вашем обработчике событий listBox1_SelectedIndexChanged вы можете сделать что-то вроде:

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    labelCodeNumber.Text = modules[listBox1.SelectedValue].Code;
}

Вы также можете рассмотреть возможность привязки объекта Module к списку 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);            
    }


}
3 голосов
/ 31 марта 2012

Я думаю, это будет делать то, что вы хотите:

    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 со всеми свойствами модуля.Заполните список объектов Module из файла XML и установите его в качестве источника данных для списка.ListBox имеет свойство DisplayMember, которое можно установить на имя свойства, которое вы хотите отобразить в ListBox, например, «Имя».Если вы сделаете это так, тогда свойство SelectedValue будет экземпляром Module, и вы сможете напрямую обращаться к его свойствам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...