none
Building an App using the DataviewModel getting its data from external XML

    Question

  • hi ,

    I'm new to this so bear with me If I'm completely throghn off track.

    I'm trying to build an app that uses an external XML file to get its content using the Split screen template in VS2012

    I've been searching high and low and must admit that My head is spinning by now of all the different ways to do this.

    I found a lot of help in other posts and boing the Windows 8 Camp in a Box was a great help.

    but all the posts I can find about parsing XML files are with very simple XML structures.

    My XML file has a structure simular to this: (Hope the image shows the idea, the <Committee> tags are wraped in <Committees></Committees>)

    Point is there are multiple Committees that contain multiple Agendas, that contains multiple Items and multiple Documents.

    After watching some Videos by Bob Tabor and doing the Windows 8 Camp in a box and searching the web I came up with the DataSource.cs structure as shown here:

    The DataSource.cs has ended up like this:

    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Xml.Linq;
    
    namespace eDagsorden.Data
    {
      [Windows.Foundation.Metadata.WebHostHidden]
        public abstract class DataCommon : eDagsorden.Common.BindableBase
        {
            internal  static Uri _baseUri = new Uri("ms-appx:///");
    
            public DataCommon(String id, String name)
            {
                this.id = id;
                this.name = name;
            }
    
            private string id = string.Empty;
            public string Id
            {
                get { return this.id; }
                set { this.SetProperty(ref this.id, value); }
            }
    
            private string name = string.Empty;
            public string Name
            {
                get { return this.name; }
                set { this.SetProperty(ref this.name, value); }
            }
        }
     public class DocumentData : DataCommon
        {
            public DocumentData(string id, string name, string itemId, string agendaId, string sourceFileName, string documentType)
                : base(id, name)
            {
                this.itemId = itemId;
                this.agendaId = agendaId;
                this.sourceFileName = sourceFileName;
                this.documentType = documentType;
            }
    
            private string itemId = string.Empty;
            public string ItemId
            {
                get { return this.itemId; }
                set { this.SetProperty(ref this.itemId, value); }
            }
            private string agendaId = string.Empty;
            public string AgendaId
            {
                get { return this.agendaId; }
                set { this.SetProperty(ref this.agendaId, value); }
            }
            private string sourceFileName = string.Empty;
            public string SourceFileName
            {
                get { return this.sourceFileName; }
                set { this.SetProperty(ref this.sourceFileName, value); }
            }
            private string documentType = string.Empty;
            public string DocumentType
            {
                get { return this.documentType; }
                set { this.SetProperty(ref this.documentType, value); }
            }
        }
    
        public class ItemData : DataCommon
        {
            public ItemData(string id, string name, string agendaId, string committeeId, string number, string sortering, string presentations, string isOpen)
                : base(id, name)
            {
                this.agendaId = agendaId;
                this.committeeId = committeeId;
                this.number = number;
                this.sortering = sortering;
                this.presentations = presentations;
                this.isOpen = isOpen;
            }
    
            private string agendaId = string.Empty;
            public string AgendaId
            {
                get { return this.agendaId; }
                set { this.SetProperty(ref this.agendaId, value); }
            }
            private string committeeId = string.Empty;
            public string CommitteeId
            {
                get { return this.committeeId; }
                set { this.SetProperty(ref this.committeeId, value); }
            }
            private string number = string.Empty;
            public string Number
            {
                get { return this.number; }
                set { this.SetProperty(ref this.number, value); }
            }
            private string sortering = string.Empty;
            public string Sortering
            {
                get { return this.sortering; }
                set { this.SetProperty(ref this.sortering, value); }
            }
            private string presentations = string.Empty;
            public string Presentations
            {
                get { return this.presentations; }
                set { this.SetProperty(ref this.presentations, value); }
            }
            private string isOpen = string.Empty;
            public string IsOpen
            {
                get { return this.isOpen; }
                set { this.SetProperty(ref this.isOpen, value); }
            }
        }
    
        public class AgendaData : DataCommon
        {
            public AgendaData(string id, string name, string committeeName, string committeeId, string meetingStart, string meetingEnd, string meetingLocation, ObservableCollection<ItemData> items, ObservableCollection<DocumentData> documents)
                : base(id, name)
            {
                this.committeeName = committeeName;
                this.committeeId = committeeId;
                this.meetingstart = meetingStart;
                this.meetingEnd = meetingEnd;
                this.meetingLocation = meetingLocation;
                this.items = items;
                this.documents = documents;
            }
    
            private string committeeName = string.Empty;
            public string CommitteeName
            {
                get { return this.committeeName; }
                set { this.SetProperty(ref this.committeeName, value); }
            }
            private string committeeId = string.Empty;
            public string CommitteeId
            {
                get { return this.committeeId; }
                set { this.SetProperty(ref this.committeeId, value); }
            }
            private string meetingstart = string.Empty;
            public string Meetingstart
            {
                get { return this.meetingstart; }
                set { this.SetProperty(ref this.meetingstart, value); }
            }
            private string meetingEnd = string.Empty;
            public string MeetingEnd
            {
                get { return this.meetingEnd; }
                set { this.SetProperty(ref this.meetingEnd, value); }
            }
            private string meetingLocation = string.Empty;
            public string MeetingLocation
            {
                get { return this.meetingLocation; }
                set { this.SetProperty(ref this.meetingLocation, value); }
            }
            private ObservableCollection<ItemData> items;
            public ObservableCollection<ItemData> Items
            {
                get { return this.items; }
                set { this.SetProperty(ref this.items, value); }
            }
            private ObservableCollection<DocumentData> documents;
            public ObservableCollection<DocumentData> Documents
            {
                get { return this.documents; }
                set { this.SetProperty(ref this.documents, value); }
            }
        }
    
        public class CommitteeDataGroup : DataCommon
        {
            public CommitteeDataGroup(string id, string name, string sourceId, ObservableCollection<AgendaData> agendas)
                : base(id, name)
            {
                this.sourceId = sourceId;
                this.agendas = agendas;
            }
            private string sourceId = string.Empty;
            public string SourceId
            {
                get { return this.sourceId; }
                set { this.SetProperty(ref this.sourceId, value); }
            }
            private ObservableCollection<AgendaData> agendas;
            public ObservableCollection<AgendaData> Agendas
            {
                get { return this.agendas; }
                set { this.SetProperty(ref this.agendas, value); }
            }
            public IEnumerable<AgendaData> TopItems
            {
                // Provides a subset of the full items collection to bind to from a GroupedItemsPage
                // for two reasons: GridView will not virtualize large items collections, and it
                // improves the user experience when browsing through groups with large numbers of
                // items.
                //
                // A maximum of 12 items are displayed because it results in filled grid columns
                // whether there are 1, 2, 3, 4, or 6 rows displayed
                get { return this.agendas.Take(12); }
            }
            public int AgendaCount
            {
                get
                {
                    return this.Agendas.Count;
                }
            }
    }
     public sealed class CommitteeDataSource
        {
            private static CommitteeDataSource committeedatasource = new CommitteeDataSource();
    
            private ObservableCollection<CommitteeDataGroup> allGroups = new ObservableCollection<CommitteeDataGroup>();
            public ObservableCollection<CommitteeDataGroup> AllGroups
            {
                get { return this.allGroups; }
            }
            public static IEnumerable<CommitteeDataGroup> GetGroups(string id)
            {
                if (!id.Equals("AllGroups")) throw new ArgumentException("Only 'AllGroups' is supported as a collection of groups");
                return committeedatasource.AllGroups;
            }
            public static CommitteeDataGroup GetCommittees(string id)
            {
                var matches = committeedatasource.AllGroups.Where((group) => group.Id.Equals(id));
                if (matches.Count() == 1) return matches.First();
                return null;
            }
            public static AgendaData GetAgendas(string id)
            {
                var matches = committeedatasource.AllGroups.SelectMany(group => group.Agendas).Where((agenda) => agenda.Id.Equals(id));
                if (matches.Count() == 1) return matches.First();
                return null;
            }
            public static async Task LoadRemoteDataAsync()
            {
               //string[] array = XDocument.Load(@"http://www.guldborgsund.dk/eDagsorden/committees.xml").Descendants("Committee").Select(element => element.Value).ToArray();
    
               var client = new HttpClient();
                client.MaxResponseContentBufferSize = 1024 * 1024;
                var response = await client.GetStreamAsync(new Uri("http://www.guldborgsund.dk/edagsorden/committees.xml"));
                
    
                //var reader = XmlReader.Create(result);
                CreateAgendasAndCommitteeGroups(XDocument.Load(response).Nodes().Ancestors("Committee").ToArray());
            }
            private static void CreateAgendasAndCommitteeGroups(Array array)
            {
                        }
    
        }
    }

    As you can see I've tried some different things in the end to actually get the data from the XML file into the ObservableCollections.

    But I'm more confused now then ever, gotten lost here.

    So what is the easiest way to get my XML to fit into the defaultviewmodel?

    A even tried to bind the XML directly into the Xaml, as described in a post on StackOverflow, but it dident Work for me.

    Can someone help me in the right direction getting past this point or point me in the right direction.

    Kind Regards,

    Jonas Christoffersen

    Monday, June 10, 2013 10:08 PM

Answers

  • Here is example on how to bind the observable collection to listview/gridview items based on earlier datamodel classes. On same basis you can layout other properties.

    xaml

     <ListView ItemsSource="{Binding Committees}">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <Grid Width="600" Height="30">
                                    <TextBlock Text="{Binding Name}" Width="120" Height="30" />
                                </Grid>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>

    cs

    protected override async void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
            {
                this.DefaultViewModel["Committees"] = await readXmlAsync();
            }

    Refer Data binding overview (Windows Store apps using C#/VB/C++ and XAML) for more details.

    For iterating through individual items, here is example

    // foreach implementation
                ObservableCollection<Committee> lstCommittees = this.DefaultViewModel["Committees"] as ObservableCollection<Committee>;
                if (lstCommittees != null)
                {
                    foreach (Committee committee in lstCommittees)
                    {
                        string committeeName = committee.Name;
                        foreach (CommitteeAgenda committeeAgenda in committee.Agendas)
                        {
                            string committeeAgendaIdentifier = committeeAgenda.Name;
                        }
                    }
                }


    Thanks,
    Sachin

    My Samples




    Wednesday, June 12, 2013 10:30 PM

All replies

  • You can create a classes for Committee, Agenda, Item and Document with properties as shown in your first diagram. Also Committee will have have public property holding ObservableCollection<Agenda>, Agenda will have ObservableCollection<Item> and ObservableCollection<Document>. Now you should be able to directly create a object of top level Committee class and serialize/deserialize that using XmlSerializer

    Also it depends on how you want to display the data. You can create a ObservableCollection of Committee and bind that to ListView/GridView source and display that using DataTemplate. Set the Committee object as source to DefaultViewModel or DataContext. 


    Thanks,
    Sachin
    My Samples


    Tuesday, June 11, 2013 2:25 PM
  • Thanks I can see the potentiols in XMLSerializer if I read your link right.

    I have done this:

    public static async Task LoadRemoteDataAsync()
            {
                var client = new HttpClient();
                client.MaxResponseContentBufferSize = 1024 * 1024;
                var response = await client.GetStreamAsync(new Uri("http://www.guldborgsund.dk/edagsorden/committees.xml"));
                XmlSerializer serializer = new XmlSerializer(typeof(CommitteeDataGroup));
    
                CommitteeDataGroup Committees;
                Committees = (CommitteeDataGroup)serializer.Deserialize(response);
    
    
            }

    But I think I have still missed the point...

    What is the Object that the XMLSerializer leaves me with in Committees and how do I get this into an Observablecollection so I can use it to Bind to the DefaultViewModel?

    I tried to add it to the App.xaml.cs like this:

    if (args.PreviousExecutionState == ApplicationExecutionState.Running)
                    {
                        Window.Current.Activate();
                        return;
                    }
                    await CommitteeDataSource.LoadRemoteDataAsync();

    And then in the Xaml page files change the SampleDataSource to CommitteeDataSource

    that dident Work, then I tried to set it to bind to Committees, but then it just sais that the name "Committees" does not exist in the namespace "using:edagsorden.Data".

    Tuesday, June 11, 2013 7:14 PM
  • I think I almost figured it out.

    I have no errors left anyway....

    But when I try to run the app I get the error:

    +  InnerException {"<ArrayOfCommittee xmlns=''> was not expected."} System.Exception {System.InvalidOperationException}

    the <ArrayOfCommittee xmlns=''> is the secound line in the XML file after the XML 1.0 line thing.

    Any surgestions?

    Kind Regards,

    Jonas 

    Tuesday, June 11, 2013 10:33 PM
  • Can you show the code where you getting this exception? 

    Thanks,
    Sachin
    My Samples

    Tuesday, June 11, 2013 10:42 PM
  • I was in between writing the sample classes for this, so here is working code. It serializes and deserializes the xml

    public class CommitteeDataModel
        {
            public CommitteeDataModel()
            {            
            }
    
            public static ObservableCollection<Committee> GetCommittees()
            {
                ObservableCollection<Committee> committee = new ObservableCollection<Committee>();
                committee.Add(new Committee() { Name = "Committee I" });
                committee.Add(new Committee() { Name = "Committee II" });
                committee.Add(new Committee() { Name = "Committee III" });
                return committee;
            }
        }
    
        public class Committee
        {
            public string Name { get; set; }
            public ObservableCollection<CommitteeAgenda> Agendas { get; set; }
            public Committee()
            {
                Agendas = new ObservableCollection<CommitteeAgenda>();
                Agendas.Add(new CommitteeAgenda() { Name = "CommitteeAgenda I" });
                Agendas.Add(new CommitteeAgenda() { Name = "CommitteeAgenda II" });
                Agendas.Add(new CommitteeAgenda() { Name = "CommitteeAgenda III" });
            }
        }
    
        public class CommitteeAgenda
        {
            public string Name { get; set; }
            public ObservableCollection<CommitteeAgendaItem> CommitteeAgendaItems { get; set; }
            public ObservableCollection<CommitteeAgendaDocument> CommitteeAgendaDocuments { get; set; }
            public CommitteeAgenda()
            {
                CommitteeAgendaItems = new ObservableCollection<CommitteeAgendaItem>();
                CommitteeAgendaItems.Add(new CommitteeAgendaItem() { Name = "CommitteeAgendaItem I" });
                CommitteeAgendaItems.Add(new CommitteeAgendaItem() { Name = "CommitteeAgendaItem II" });
                CommitteeAgendaItems.Add(new CommitteeAgendaItem() { Name = "CommitteeAgendaItem III" });
    
                CommitteeAgendaDocuments = new ObservableCollection<CommitteeAgendaDocument>();
                CommitteeAgendaDocuments.Add(new CommitteeAgendaDocument() { Name = "CommitteeAgendaDocument I" });
                CommitteeAgendaDocuments.Add(new CommitteeAgendaDocument() { Name = "CommitteeAgendaDocument II" });
                CommitteeAgendaDocuments.Add(new CommitteeAgendaDocument() { Name = "CommitteeAgendaDocument III" });
            }
        }
    
        public class CommitteeAgendaItem
        {
            public string Name { get; set; }
    
            public CommitteeAgendaItem()
            {
    
            }
        }
    
        public class CommitteeAgendaDocument
        {
            public string Name { get; set; }
    
            public CommitteeAgendaDocument()
            {
    
            }
        }
    
        public sealed partial class CommitteePage : TestApp2.Common.LayoutAwarePage
        {
            public CommitteePage()
            {
                this.InitializeComponent();
                
            }
    
            protected override async void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
            {
                this.DefaultViewModel["Committees"] = await readXmlAsync();
            }
    
            async Task writeXmlAsync()
            {
                IStorageFile xmlFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("Committees.xml", CreationCollisionOption.ReplaceExisting);
    
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(ObservableCollection<Committee>));
                MemoryStream memoryStream = new MemoryStream();
                ObservableCollection<Committee> committees = CommitteeDataModel.GetCommittees();
                xmlSerializer.Serialize(memoryStream, committees);
                memoryStream.Seek(0, SeekOrigin.Begin);
                string serialized = new StreamReader(memoryStream).ReadToEnd();
                memoryStream.Dispose();
    
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(serialized);
    
                await xmlDoc.SaveToFileAsync(xmlFile);
            }
    
            async Task<ObservableCollection<Committee>> readXmlAsync()
            {
                ObservableCollection<Committee> committeesRead = null;
                IStorageFile xmlReadFile = await ApplicationData.Current.LocalFolder.GetFileAsync("Committees.xml");
                using (Stream stream = await xmlReadFile.OpenStreamForReadAsync())
                {
                    XmlSerializer xmlReadSerializer = new XmlSerializer(typeof(ObservableCollection<Committee>));
                    committeesRead = xmlReadSerializer.Deserialize(stream) as ObservableCollection<Committee>;
                }
                return committeesRead;
            }
    
            protected override void SaveState(Dictionary<String, Object> pageState)
            {
              
            }

    serialized xml file

    <?xml version="1.0"?><ArrayOfCommittee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Committee>
        <Name>Committee I</Name>
        <Agendas>
          <CommitteeAgenda>
            <Name>CommitteeAgenda I</Name>
            <CommitteeAgendaItems>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem I</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem II</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem III</Name>
              </CommitteeAgendaItem>
            </CommitteeAgendaItems>
            <CommitteeAgendaDocuments>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument I</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument II</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument III</Name>
              </CommitteeAgendaDocument>
            </CommitteeAgendaDocuments>
          </CommitteeAgenda>
          <CommitteeAgenda>
            <Name>CommitteeAgenda II</Name>
            <CommitteeAgendaItems>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem I</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem II</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem III</Name>
              </CommitteeAgendaItem>
            </CommitteeAgendaItems>
            <CommitteeAgendaDocuments>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument I</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument II</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument III</Name>
              </CommitteeAgendaDocument>
            </CommitteeAgendaDocuments>
          </CommitteeAgenda>
          <CommitteeAgenda>
            <Name>CommitteeAgenda III</Name>
            <CommitteeAgendaItems>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem I</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem II</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem III</Name>
              </CommitteeAgendaItem>
            </CommitteeAgendaItems>
            <CommitteeAgendaDocuments>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument I</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument II</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument III</Name>
              </CommitteeAgendaDocument>
            </CommitteeAgendaDocuments>
          </CommitteeAgenda>
        </Agendas>
      </Committee>
      <Committee>
        <Name>Committee II</Name>
        <Agendas>
          <CommitteeAgenda>
            <Name>CommitteeAgenda I</Name>
            <CommitteeAgendaItems>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem I</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem II</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem III</Name>
              </CommitteeAgendaItem>
            </CommitteeAgendaItems>
            <CommitteeAgendaDocuments>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument I</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument II</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument III</Name>
              </CommitteeAgendaDocument>
            </CommitteeAgendaDocuments>
          </CommitteeAgenda>
          <CommitteeAgenda>
            <Name>CommitteeAgenda II</Name>
            <CommitteeAgendaItems>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem I</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem II</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem III</Name>
              </CommitteeAgendaItem>
            </CommitteeAgendaItems>
            <CommitteeAgendaDocuments>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument I</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument II</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument III</Name>
              </CommitteeAgendaDocument>
            </CommitteeAgendaDocuments>
          </CommitteeAgenda>
          <CommitteeAgenda>
            <Name>CommitteeAgenda III</Name>
            <CommitteeAgendaItems>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem I</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem II</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem III</Name>
              </CommitteeAgendaItem>
            </CommitteeAgendaItems>
            <CommitteeAgendaDocuments>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument I</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument II</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument III</Name>
              </CommitteeAgendaDocument>
            </CommitteeAgendaDocuments>
          </CommitteeAgenda>
        </Agendas>
      </Committee>
      <Committee>
        <Name>Committee III</Name>
        <Agendas>
          <CommitteeAgenda>
            <Name>CommitteeAgenda I</Name>
            <CommitteeAgendaItems>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem I</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem II</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem III</Name>
              </CommitteeAgendaItem>
            </CommitteeAgendaItems>
            <CommitteeAgendaDocuments>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument I</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument II</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument III</Name>
              </CommitteeAgendaDocument>
            </CommitteeAgendaDocuments>
          </CommitteeAgenda>
          <CommitteeAgenda>
            <Name>CommitteeAgenda II</Name>
            <CommitteeAgendaItems>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem I</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem II</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem III</Name>
              </CommitteeAgendaItem>
            </CommitteeAgendaItems>
            <CommitteeAgendaDocuments>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument I</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument II</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument III</Name>
              </CommitteeAgendaDocument>
            </CommitteeAgendaDocuments>
          </CommitteeAgenda>
          <CommitteeAgenda>
            <Name>CommitteeAgenda III</Name>
            <CommitteeAgendaItems>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem I</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem II</Name>
              </CommitteeAgendaItem>
              <CommitteeAgendaItem>
                <Name>CommitteeAgendaItem III</Name>
              </CommitteeAgendaItem>
            </CommitteeAgendaItems>
            <CommitteeAgendaDocuments>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument I</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument II</Name>
              </CommitteeAgendaDocument>
              <CommitteeAgendaDocument>
                <Name>CommitteeAgendaDocument III</Name>
              </CommitteeAgendaDocument>
            </CommitteeAgendaDocuments>
          </CommitteeAgenda>
        </Agendas>
      </Committee>
    </ArrayOfCommittee>


    Thanks,
    Sachin
    My Samples


    Tuesday, June 11, 2013 11:09 PM
  • Thanks Sachin.

    That is actually great, now I feel competely stupid to ask...

    It Works in your sample but you specify eatch Item in the class

    public class Committee
        {
            public string Name { get; set; }
            public ObservableCollection<CommitteeAgenda> Agendas { get; set; }
            public Committee()
            {
                Agendas = new ObservableCollection<CommitteeAgenda>();
                Agendas.Add(new CommitteeAgenda() { Name = "CommitteeAgenda I" });
                Agendas.Add(new CommitteeAgenda() { Name = "CommitteeAgenda II" });
                Agendas.Add(new CommitteeAgenda() { Name = "CommitteeAgenda III" });
            }
        }

    I can't use Agendas.Add...

    because I woudent know how many agendas are in the Collection as that changes frequently.

    So I somehow need to itterate through it.

    I was thinking a foreach loop but Im not sure how to construct that

    Also your readXmlAsync() returns committeesRead

    I gues this would be the deserialized ObservableCollection that holds all the data?

    I tried implementing your sample into mine and Stepping through the Debug I can see that all the data from the XML file is being read in but Im completely lost in how to get to it.

    The Camp In a box uses a JSON Array but after thay get the data they do the following:

    private static void CreateRecipesAndRecipeGroups(JsonArray array)
            {
                foreach (var item in array)
                {
                    var obj = item.GetObject();
                    RecipeDataItem recipe = new RecipeDataItem();
                    RecipeDataGroup group = null;
    
                    foreach (var key in obj.Keys)
                    {
                        IJsonValue val;
                        if (!obj.TryGetValue(key, out val))
                            continue;
    
                        switch (key)
                        {
                            case "key":
                                recipe.UniqueId = val.GetNumber().ToString();
                                break;
                            case "title":
                                recipe.Title = val.GetString();
                                break;
                            case "shortTitle":
                                recipe.ShortTitle = val.GetString();
                                break;
                            case "preptime":
                                recipe.PrepTime = (int)val.GetNumber();
                                break;
                            case "directions":
                                recipe.Directions = val.GetString();
                                break;
                            case "ingredients":
                                var ingredients = val.GetArray();
                                var list = (from i in ingredients select i.GetString()).ToList();
                                recipe.Ingredients = new ObservableCollection<string>(list);
                                break;
                            case "backgroundImage":
                                recipe.SetImage(val.GetString());
                                break;
                            case "tileImage":
                                recipe.SetTileImage(val.GetString());
                                break;
                            case "group":
                                var recipeGroup = val.GetObject();
    
                                IJsonValue groupKey;
                                if (!recipeGroup.TryGetValue("key", out groupKey))
                                    continue;
    
                                group = _recipeDataSource.AllGroups.FirstOrDefault(c => c.UniqueId.Equals(groupKey.GetString()));
    
                                if (group == null)
                                    group = CreateRecipeGroup(recipeGroup);
    
                                recipe.Group = group;
                                break;
                        }
                    }
    
                    if (group != null)
                        group.Items.Add(recipe);
                }
            }
            
            private static RecipeDataGroup CreateRecipeGroup(JsonObject obj)
            {
                RecipeDataGroup group = new RecipeDataGroup();
    
                foreach (var key in obj.Keys)
                {
                    IJsonValue val;
                    if (!obj.TryGetValue(key, out val))
                        continue;
    
                    switch (key)
                    {
                        case "key":
                            group.UniqueId = val.GetString();
                            break;
                        case "title":
                            group.Title = val.GetString();
                            break;
                        case "shortTitle":
                            group.ShortTitle = val.GetString();
                            break;
                        case "description":
                            group.Description = val.GetString();
                            break;
                        case "backgroundImage":
                            group.SetImage(val.GetString());
                            break;
                        case "groupImage" :
                            group.SetGroupImage(val.GetString());
                            break; 
                    }
                }
    
                _recipeDataSource.AllGroups.Add(group);
                return group;
            }
        }

    If I read it right they step through the array creating the groups that will be displayed in the Xaml.

    My guess is that I have to do something simular to my data?

    Wednesday, June 12, 2013 8:28 AM

  • I can't use Agendas.Add...

    because I woudent know how many agendas are in the Collection as that changes frequently.


    All Add inside constructor is just dummy data. We can add agenda to any collection defined in those classes using Add outside the class once we have object for it.

    If I understand correctly, you will have a xml file which you want to read -

    1. readXmlAsync will provide us a collection of Committee. (you also mentioned the same) - ObservableCollection<Committee>

    2. Now once we have collection we can just iterate over it using foreach (Committee c in collection received)

    3. Inside the foreach loop, it's now up to us we can drill down and query other properties of Committee, like Agenda collection (ObservableCollection<CommitteeAgenda>) through public property and likewise for other things.

    You would not need JSON in this case as it is xml format not json.

    Hope this helps.


    Thanks,
    Sachin
    My Samples


    Wednesday, June 12, 2013 3:27 PM
  • Still dont get it... Sorry :-)

    I have in my DataSource fil

     public static async Task<ObservableCollection<Committee>> LoadRemoteDataAsync()
                {
                    ObservableCollection<Committee> committeesRead = null;
                    var client = new HttpClient();
                    client.MaxResponseContentBufferSize = 1024 * 1024;
                    var response = await client.GetStreamAsync(new Uri("http://www.guldborgsund.dk/edagsorden/committees.xml"));
                    XmlSerializer Readserializer = new XmlSerializer(typeof(ObservableCollection<Committee>));
                    committeesRead = Readserializer.Deserialize(response) as ObservableCollection<Committee>;
    
    
                    return committeesRead;
    
                }

    This returns the committeesRead to the call from App.Xaml.cs

    if (args.PreviousExecutionState == ApplicationExecutionState.Running)
                    {
                        Window.Current.Activate();
                        return;
                    }
                    await eDagsorden.Data.CommitteeDataModel.CommitteeDataSource.LoadRemoteDataAsync();
                   
                    // Place the frame in the current Window
                    Window.Current.Content = rootFrame;

    but then the ItemsPage.Xaml.cs makes a call to the GetGroups

    When I step through the code I I can see that the XML file is indeed loaded into the committesRead

    and the GetGroup does not through the exception as it does get Committee, but the IEnumerable<Committee> returns null

    My best gues is that I need to store the committeesRead in some variable

    and then use a foreach(Committe c in committeesRead)

    ???

    I can see that committeeRead holds the Committee[0].Name and so on, but I just can't get around to access it unless I specifically asks for committee[0]

    Im starting to get the feeling that My issue has not been with the loading of the XML but my understanding of how the ViewModel Works in Store Apps and the ObservableCollection object.

    When I get back to my desk tomorrow I'll Post what I got so fare, that might make it easier to spot my mistakes :-)
    • Edited by jocit Wednesday, June 12, 2013 10:16 PM update
    Wednesday, June 12, 2013 10:15 PM
  • Here is example on how to bind the observable collection to listview/gridview items based on earlier datamodel classes. On same basis you can layout other properties.

    xaml

     <ListView ItemsSource="{Binding Committees}">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <Grid Width="600" Height="30">
                                    <TextBlock Text="{Binding Name}" Width="120" Height="30" />
                                </Grid>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>

    cs

    protected override async void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
            {
                this.DefaultViewModel["Committees"] = await readXmlAsync();
            }

    Refer Data binding overview (Windows Store apps using C#/VB/C++ and XAML) for more details.

    For iterating through individual items, here is example

    // foreach implementation
                ObservableCollection<Committee> lstCommittees = this.DefaultViewModel["Committees"] as ObservableCollection<Committee>;
                if (lstCommittees != null)
                {
                    foreach (Committee committee in lstCommittees)
                    {
                        string committeeName = committee.Name;
                        foreach (CommitteeAgenda committeeAgenda in committee.Agendas)
                        {
                            string committeeAgendaIdentifier = committeeAgenda.Name;
                        }
                    }
                }


    Thanks,
    Sachin

    My Samples




    Wednesday, June 12, 2013 10:30 PM