2016-04-07 7 views
1

Beim Erstellen einer Methode zum generischen Hinzufügen zu einem ObservableCollection aus einer XML Datei ist jeder Datensatz der letzte gelesen.Poping ObservableCollection aus XML-Datei generisch

Ich muss mehrere XML Dateien in mehrere ObservableCollection laden. Dies ist einfach genug, aber diese ObservableCollection basierend auf mehreren Classes und mehr wird hinzugefügt werden, nicht zu erwähnen, dass Änderungen an der bestehenden Classes müssten in der Lesung von XML Datei wiedergegeben werden. Also dachte ich, dass eine Methode, die eine generische ObservableCollection<object> zurückgeben würde, dies lösen würde. Wenn die Methode aufgerufen wird, würde die Class der ObservableCollection etwas wie diese werfen;

MyClass c = new MyClass(); 
GetXMLData(c); 

Dann in der Methode für jedes XElement würde ich jede Eigenschaft so etwas setzen;

public ObservableCollection<object> GetXMLData(object value) 
{ 
    string fName = "MyPath"; 
    ObservableCollection<object> tableData = new ObservableCollection<object>(); 
    FileStream fs = new FileStream(fName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
    { 
     XDocument fileXML = XDocument.Load(fs); 
     var dataXML = 
      from x in fileXML.Descendants("MyData") 
      select x; 
     foreach (XElement x in dataXML) 
     { 
      var data = (object)value; 
      foreach (var prop in value.GetType().GetProperties()) 
      { 
        PropertyInfo propertyInfo = data.GetType().GetProperty(prop.Name); 
        propertyInfo.SetValue(data, Convert.ChangeType(x.Attribute(prop.Name).Value, propertyInfo.PropertyType), null); 
      } 
      tableData.Add(data); 
     } 
    } 
    return tableData; 
} 

Diese Art von Arbeiten, aber es hat ein Problem. Da ich Daten auf Wert, werfe, ist jede DatensatztabelleData der letzte gelesene Datensatz.

Say XML-Daten wie folgt aussieht:

<Item Field1="Bob" Field2="10" /> 
<Item Field1="Mike" Field2="20" /> 
<Item Field1="Sam" Field2="30" /> 

Wenn Sie ObservableCollection<object> schauen Sie sehen:

Field1="Sam", Field2="30" 
Field1="Sam", Field2="30" 
Field1="Sam", Field2="30" 

statt dies zu sehen:

Field1="Bob", Field2="10" 
Field1="Mike" Field2="20" 
Field1="Sam" Field2="30" 

Anmerkungen:

  1. Ich habe Logik für die Fehlerbehandlung mit schlechten Daten, die nicht da sind. So ignoriert, dass
  2. Sie können sicher davon ausgehen, dass die XML-Datei übereinstimmen Attribute perfekt für die Klasse

edit: versuchte, meine Frage zu klären. Entschuldigung wollte zeigen, was ich nicht gerade "Hey wie machst du das?"

+1

Was * genau * ist deine Frage? Ich sehe hier keine spezifische Frage. – GEEF

+0

@GEEF Bitte schauen Sie sich die Frage an, ich erwähne die Frage deutlicher. – Xaphann

Antwort

1

Nun ... alle Instanzen von data in Ihrer Schleife sind eigentlich Verweise auf value. Sie sind keine "neuen" Objekte. Also, was Sie in jeder Schleife tun, ändert die Eigenschaften von value, die ich sicher nicht was Sie wollen. Wenn Sie Debug.WriteLine(value), bei jeder Wiederholung, werden Sie sehen, was ich meine. So sind alle drei data Instanzen und value immer gleich. Wenn Sie wissen, was der Typ value ist, sollten Sie neue Instanzen davon erstellen, legen Sie die Eigenschaften entsprechend fest. Angenommen, der Typ hat einen öffentlichen Konstruktor, der kein Argument ist:

... würden Sie beginnen.

+0

Vielen Dank !!! Ich verstand, warum es geschah, aber der Schlüssel Activator.CreateInstance. Alles, was ich versucht habe. GetType() funktionierte nicht. – Xaphann

+0

Yup - das ist die magische Kugel für so etwas ;-) – Clay