DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Data Engineering
  3. Data
  4. Developing the ImagineCup WorldWide Finals Tracker app fro WP7 @ ImagineCup - Part 1

Developing the ImagineCup WorldWide Finals Tracker app fro WP7 @ ImagineCup - Part 1

Denzel D. user avatar by
Denzel D.
·
Jul. 09, 11 · Interview
Like (0)
Save
Tweet
Share
5.02K Views

Join the DZone community and get the full member experience.

Join For Free

ImagineCup Worldwide Finals is a huge event where everything is going on so fast, that it is ultimately necessary to carry a schedule around just to make sure that one won't miss something important. The ImagineCup Worldwide Finals Tracker is a Windows Phone application that is built to make it easier to navigate through all the events going on in the context of ImagineCup in New York.

One of the main goals of this application was to make its core reusable for the next ImagineCup competitions. Therefore, code flexibility and UI generalization were a priority. I decided to implement simple Metro tiles as the main starting point - a way to keep the user in the WP7 "comfort zone".

The UI structure was built around the idea that the same content skeleton will be used year by year, the same being applied to internal content structure. In XAML, I decided to simply use a bunch of Grid controls inside a StackPanel:

<StackPanel Width="480" Grid.Row="2">
            <ScrollViewer Height="570" VerticalScrollBarVisibility="Visible">
               <StackPanel>
                   <StackPanel Height="200" Margin="0,0,0,10" Orientation="Horizontal">
                        <Grid Margin="35,0,10,0" Height="200" Width="200" Background="{StaticResource PhoneAccentBrush}">
                            <Image MouseLeftButtonUp="Image_MouseLeftButtonUp" Source="Images/metro_world.png" Height="110" Width="110" Margin="0,0,0,50"></Image>
                            <TextBlock TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeExtraLarge}" FontFamily="{StaticResource PhoneFontFamilyLight}" Text="teams" Foreground="White" Height="Auto" Margin="10,130,10,0"></TextBlock>
                        </Grid>

                        <Grid Height="200" Width="200" Background="{StaticResource PhoneAccentBrush}">
                            <Image Source="Images/metro_coverage.png" Height="110" Width="110" Margin="0,0,0,50"></Image>
                            <TextBlock TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeExtraLarge}" FontFamily="{StaticResource PhoneFontFamilyLight}" Text="coverage" Foreground="White" Height="Auto" Margin="10,130,10,0"></TextBlock>
                        </Grid>
                    </StackPanel>

                    <StackPanel Margin="0,0,0,10" Orientation="Horizontal">
                        <Grid Margin="35,0,10,0" Height="200" Width="200" Background="{StaticResource PhoneAccentBrush}">
                            <Image Source="Images/metro_schedule.png" Height="110" Width="110" Margin="0,0,0,50"></Image>
                            <TextBlock TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeExtraLarge}" FontFamily="{StaticResource PhoneFontFamilyLight}" Text="schedule" Foreground="White" Height="Auto" Margin="10,130,10,0"></TextBlock>
                        </Grid>

                        <Grid Height="200" Width="200" Background="{StaticResource PhoneAccentBrush}">
                            <Image Source="Images/metro_alerts.png" Height="110" Width="110" Margin="0,0,0,50"></Image>
                            <TextBlock TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeExtraLarge}" FontFamily="{StaticResource PhoneFontFamilyLight}" Text="alerts" Foreground="White" Height="Auto" Margin="10,130,10,0"></TextBlock>
                        </Grid>
                    </StackPanel>


                    <StackPanel Margin="0,0,0,10" Orientation="Horizontal">
                        <Grid Margin="35,0,10,0" Height="200" Width="200" Background="{StaticResource PhoneAccentBrush}">
                            <Image Source="Images/metro_nyc_info.png" Height="110" Width="110" Margin="0,0,0,50"></Image>
                            <TextBlock TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeExtraLarge}" FontFamily="{StaticResource PhoneFontFamilyLight}" Text="nyc info" Foreground="White" Height="Auto" Margin="10,130,10,0"></TextBlock>
                        </Grid>

                        <Grid Height="200" Width="200" Background="{StaticResource PhoneAccentBrush}">
                            <Image Source="Images/metro_about.png" Height="110" Width="110" Margin="0,0,0,50"></Image>
                            <TextBlock TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeExtraLarge}" FontFamily="{StaticResource PhoneFontFamilyLight}" Text="about" Foreground="White" Height="Auto" Margin="10,130,10,0"></TextBlock>
                        </Grid>
                    </StackPanel>
                </StackPanel>
            </ScrollViewer>
        </StackPanel>

Notice that Grid controls are grouped in two and inserted in a StackPanel that represents a single row. This can generally be simplified by using a single style and a template that defines the structure, but given the limited number of elements, it is not really necessary. That's it for the main page.

Key Component 1 - Teams

It is time to see how we can get the teams that are participating in ImagineCup. Each year at the finals, we get a fixed number of teams with data related to them. Basic information includes:

  • Team Name
  • Team Location
  • Team Project
  • Project Description
  • Team Picture 

This information can be obtained in the application in two ways - either build a custom WCF service that will return the serialized data from a central storage point (like a database) or stored locally. To simplify the process, Julio Farfan created a simple XML file and included it in the project locally. We got this:

<teams>
<!--Teams from julio-->
<team>
   <location>Algeria</location>
   <name>Epsilon</name>
   <category>Software Design</category>
   <description>SurgeReal helps students and surgeons practice basic surgeries by providing a 3-D organ image and step-by-step learning. With a solution much cheaper than its competitors and other simulators, SurgeReal answers a very critical issue faced by surgeons living in difficult areas around the world.</description>
    <image>http://www.imaginecup.com/upload/5690632162_cc35b11b2f_b1806542277.jpg</image>
</team>

<team>
   <location>Armenia</location>
   <name>X-Tech</name>
   <category>Software Design</category>
   <description>Teach Me Now is an interactive process on an educational, group-based exchange platform. The system implies conditions that will apply to everyone interested in delivering trainings on an issue and those interested in acquiring new skills and knowledge.</description>
    <image>http://www.imaginecup.com/upload/DSC_3032_5inch2019136558.jpg</image>
</team>
</teams>

Of course this is just a short snippet, because the number of teams goes way beyond 100, but you can see that the structure of the file is as simple as it can get. The file is included as Content in the project, so I can easily invoke it from inside the application itself.

To parse the data out, I decided to create two models - TeamSet and Team. TeamSet represents the entire XML entity:

namespace icww.Models
{
    [XmlRoot("teams")]
    public class TeamSet
    {
        [XmlElement("team")]
        public List<Team> Teams { get; set; }
    }
}

The serialization attributes will help me automate the reading process instead of going node-by-node to read the content. Team represents a single team entity:

namespace icww.Models
{
    public class Team
    {
        [XmlIgnore()]
        public BitmapImage Logo { get; set; }
        [XmlElement("image")]
        public string LogoUrl { get; set; }
        [XmlElement("name")]
        public string Name { get; set; }
        [XmlElement("location")]
        public string Location { get; set; }
        [XmlIgnore()]
        public List<string> MemberSchools { get; set; }
        [XmlIgnore()]
        public List<string> Members { get; set; }
        [XmlElement("category")]
        public string Category { get; set; }
        [XmlElement("description")]
        public string Description { get; set; }
    }
}

There is a reason why some properties are marked with XmlIgnore. Logo is a BitmapImage that cannot be directly deserialized from an XML file. Ultimately, we could store Base64 content, but that would be costly on the amount of memory taken by the application. So the logo is updated dynamically based on the logo URL (through the LogoUrl property).

Members and MemberSchools are not defined in the XML, so it was decided to keep it here for future reference and ultimately include this data, but as long as testing goes - we can keep it simple.

Deserialization goes in a helper static class:

public static class DataInitializer
    {
        public static void GetTeams()
        {
            XDocument doc = XDocument.Load("teams.xml");
            XmlReader reader = doc.CreateReader();

            XmlSerializer serializer = new XmlSerializer(typeof(TeamSet));
            TeamSet set = (TeamSet)serializer.Deserialize(reader);

            ModelLocator.MainModel.Teams = new System.Collections.ObjectModel.ObservableCollection<Team>();
            foreach (Team t in set.Teams)
            {
                if (!string.IsNullOrEmpty(t.LogoUrl))
                {
                    t.Logo = new System.Windows.Media.Imaging.BitmapImage(new Uri(t.LogoUrl, UriKind.Absolute));
                }

                ModelLocator.MainModel.Teams.Add(t);
            }
        }

ModelLocator here is a model locator (literally) implemented through the MVVM Light framework. MainModel is bound to the team page and Teams is an ObservableCollection<Team> that is used for it's basic notification mechanism (on update).

Once the deserialization is complete, the team list on the Teams.xaml page is updated automatically - specifically the ListBox that will be used to display team information.

teams Tracker (business software) Database app application Data (computing) XML Windows Phone

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Using GPT-3 in Our Applications
  • Choosing the Right Framework for Your Project
  • Create a REST API in C# Using ChatGPT
  • How Chat GPT-3 Changed the Life of Young DevOps Engineers

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: