2012-03-31 18 views
1

リストボックスで選択したアイテムがラベル内の兄弟要素を表示するようにしたいと思います。現在、XMLファイルを使用して<Name>要素を取得し、リストボックスに<Name>の値を設定しています。ここで、<Name>がリストボックスで強調表示されると、そのモジュールに関連する<Code>がフォームのラベルに表示されるようにしたいと考えています。リストボックスの選択項目にXML要素をマッチする - C#

つまり、リストボックスのアルゴリズムとデータ構造が選択されている場合は、そのコード、容量、セメスター、および前提条件をフォームのラベルに表示します。他のいくつかのモジュールが選択されている場合は、ここで選択したモジュール

のために再びそれを行うことは、私の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(); 
      } 

     } 

誰かが私を助けることができれば、私は私は、これはあなたがやりたいだろうと思い

答えて

4

私はいくつかのステップに戻り、デザインを見ていきます。コード内でXMLに直接アクセスする頻度はどれくらいですか? ListBoxで選択されたインデックスの変更が無駄であると思われるたびにファイルを読み込み、ファイルにアクセスできない場合は例外をスローします。

あなたがXML多数回にアクセスしようとしている場合は、私はあなたの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; } 
} 

は、その後、あなたのモジュールオブジェクトのコレクションを作成し

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イベントハンドラで、あなたが行うことができますsometihngのように:

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

また、リストボックスにModuleオブジェクトをデータバインディングを検討することができますが、私は非常に精通していないですそれで、私はそこで多くの助けをすることはできません。

編集: コレクションにコードを挿入して、どのメソッドにもアクセスできるようにします。

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


} 
+0

私のコードにコレクションを入れるべき場所を教えてください。私はわからない – a7omiton

+0

これは私が下で話していた代替ソリューションです。ただし、辞書を使用する代わりに、モジュールリストを直接ListBoxに割り当ててから、DisplayMemberプロパティを設定することができます。 – aKzenT

+0

現時点であなたのリストボックスをどこに入れるのかを入れておくべきです。 – aKzenT

3

にそれを感謝してください:

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ファイルからModuleオブジェクトのリストを作成し、これをリストボックスのデータソースとして設定します。 ListBoxにはDisplayMemberというプロパティがあり、表示するプロパティの名前にはListBoxなどで設定できます。 "名"。このようにするとSelectedValueプロパティはModuleのインスタンスになり、そのプロパティに直接アクセスできます。

+0

文字列名= listBox1.SelectedValueでエラーが発生しました。文字列から型オブジェクトに変換できないと言っています – a7omiton

+0

私のエラーです。更新されたソリューション(SelectedValueでToStringを呼び出す)を参照してください – aKzenT

+0

代替ソリューションも参照してください。いずれにしても、関数からXDocument.Loadを取り出し、クラス変数に格納して、インデックスが変更されるたびにファイル全体を読み取らないようにする必要があります。 – aKzenT

関連する問題