Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

C# Tutorial: Creating a personal weather app

timer combobox

  • Please log in to reply
5 replies to this topic

#1 Parabola

Parabola

    CC Addict

  • Just Joined
  • PipPipPipPipPip
  • 221 posts

Posted 01 September 2009 - 12:13 PM

Today's project is to create an app that will display weather information from a city, including the forecast. We will be using an extra API, the animaonline weather API using google weather, which is included with the source code.
Tasks demonstrated:

  • Populating text and image fields
  • Saving user input / settings :rules: (finally figured this one out)
  • Automatically refreshing data at a specified interval
This is not a quick project, it does take a little bit of time, but it is also a project anyone should be able to do and learn something from.
For an example of the finished product, download mine here:
http://jmangum.codec...ather/setup.exe

OK, let's begin
Download the source file (attached, or go to: cweather - Project Hosting on Google Code) Included in this source is of course the code, but also the animaonline Weather API, and an icon.

Step 1: Create our project, and reference the needed API

1. Create a new project, a winforms app of course. Name it Weather.
2. Rename Form1 to weatherForm
3. Go ahead and copy the API.dll and the icon into the root folder of your project, just to make things easier.
4. Go to the references for your project, and add the animaonline weather api.
5. Add the following code to the top of the source for your weatherForm:
using Animaonline.WeatherAPI;
using System.Threading;
using Weather.Properties;

Step 2: Create user settings

1. Right click on your project, and go to properties. Then select the settings tab.
2. Create the following settings:
Posted Image
windowPosition is of type System.Drawing.Point
3. Save.

Step 3: Start declaring some variables

1. Open the code for weatherForm.designer.cs
2. Add these line in right after #endregion:
private Animaonline.WeatherAPI.WeatherData wD;
        private string City;
        private int delay;

Now before we can go much further, we have to design our form. This part takes a little more time, since we have to create all of our labels and imageboxes.

Step 4: Design the form

1. Resize the form itself. Make it 696, 231
2. This picture will show you how to make the form look, but don't actually put the text into the label's and the textbox: that's there so you know what to NAME them. leave the text blank on all of them EXCEPT Current Conditions and AutoUpdate: (name those whatever you want, they are static)
The Boxes are PictureBox's.. name them icnCurrent, icnToday, icnTomorrow, icnDay2, and icnDay3
For your comboBox, name it comboBoxEdit1. I'll give you the list items after the picture.
Posted Image
3. The comboBox:
list items are:
  • Never
  • 1 Minute
  • 2 Minutes
  • 5 Minutes
  • 10 Minutes
  • 30 Minutes
  • 1 Hour
  • 2 Hours
  • 4 Hours
Go into the properties for it, and under application settings, property binding, change the Text option to intervalText. Change dropdown style (near the top of properties) to DropDownList.
4. txtCity: Once again, application settings, property bindings: Text = defaultCity
5. Under components, add a timer. You can leave this named timer1. However, once again, go to the property bindings, and set interval to intervalTime, enabled to timerOn.
6. The form itself: data binding again, set the location to windowLocation

Step 5: Let's start coding

1. First, lets tell the program when to load and save our settings.
Under initialize component, add the following code:
delay = Settings.Default.intervalTime;
            txtCity.Text = Settings.Default.defaultCity;
            this.Location = Settings.Default.windowPosition;
            comboBoxEdit1.Text = Settings.Default.intervalText;
            timer1.Enabled = Settings.Default.timerOn;
This loads our settings.
2. We need to write a function to get the weather data and populate the fields. Here's the code:
private void getWeather(string City)
        {
            try
            {
                //Get the data
                wD = WeatherAPI.GetWeather(LanguageCode.en_US, City);

                //Set image locations
                string baseURL = "http://www.google.com";
                string iconToday = baseURL + wD.iconTODAY;
                string icon = baseURL + wD.icon;
                string iconTOMORROW = baseURL + wD.iconTOMORROW;
                string iconDAY2 = baseURL + wD.iconDAY2;
                string iconDAY3 = baseURL + wD.iconDAY3;

                //Set images
                icnCurrent.ImageLocation = icon;
                icnDay2.ImageLocation = iconDAY2;
                icnDay3.ImageLocation = iconDAY3;
                icnToday.ImageLocation = iconToday;
                icnTomorrow.ImageLocation = iconTOMORROW;

                //Current Conditions
                lblCity.Text = wD.city;
                lblCurrentCond.Text = wD.condition;
                lblCurrentF.Text = "Temperature: " + wD.temp_f.ToString() + "°F";
                lblWind.Text = wD.wind_condition;

                //Day 2's Conditions
                lblDay2.Text = wD.day_of_weekDAY2;
                lblDay2Cond.Text = wD.conditionDAY2;
                lblDay2High.Text = "High:  " + wD.highDAY2.ToString() + "°F";
                lblDay2Low.Text = "Low:  " + wD.lowDAY2.ToString() + "°F";

                //Day 3's Conditions
                lblDay3.Text = wD.day_of_weekDAY3;
                lblDay3Cond.Text = wD.conditionDAY3;
                lblDay3High.Text = "High:  " + wD.highDAY3.ToString() + "°F";
                lblDay3Low.Text = "Low:  " + wD.lowDAY3.ToString() + "°F";

                //Today's Conditions
                lblToday.Text = wD.day_of_weekTODAY;
                lblTodayCond.Text = wD.conditionTODAY;
                lblTodayHigh.Text = "High:  " + wD.highTODAY.ToString() + "°F";
                lblTodayLow.Text = "Low:  " + wD.lowTODAY.ToString() + "°F";

                //Tomorrow's Conditions
                lblTomorrow.Text = wD.day_of_weekTOMORROW;
                lblTomorrowCond.Text = wD.conditionTOMORROW;
                lblTomorrowHigh.Text = "High:  " + wD.highTOMORROW.ToString() + "°F";
                lblTomorrowLow.Text = "Low:  " + wD.lowTOMORROW.ToString() + "°F";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
Notice we use a try / catch statement. This way, if there is an error, the program won't crash, it will just tell us what happened.
3. Now go back to where we loaded the settings, and add this:
//Get Initial Weather
            City = txtCity.Text;
            getWeather(City);
Now, when the app loads, it will automatically get the weather data.
4. Now we need a function to handle the intervals
private void getDelay(string Selection)
        {
            //Set the delay based on User Selection
            if (Selection == "Never")
                delay = 1;
            if (Selection == "1 Minute")
                delay = 1;
            if (Selection == "2 Minutes")
                delay = 2;
            if (Selection == "5 Minutes")
                delay = 5;
            if (Selection == "10 Minute")
                delay = 10;
            if (Selection == "30 Minutes")
                delay = 30;
            if (Selection == "1 Hour")
                delay = 1 * 60;
            if (Selection == "2 Hours")
                delay = 2 * 60;
            if (Selection == "4 Hours")
                delay = 4 * 60;
            if (Selection == "Select AutoUpdate Interval")
                delay = 1;
            delay = (delay * 60000);
            
        }
5. Now go back and doubleclick on the button named getW.
Add the following code to that button:
//Set delay from minutes to milliseconds
            getDelay(comboBoxEdit1.Text);
            
            //Get Weather
            City = txtCity.Text;
            getWeather(City);

            //Set timer1
            if (comboBoxEdit1.Text == "Never")
            {
                timer1.Enabled = false;
            }
            else
            {
                timer1.Interval = delay;
                timer1.Enabled = true;
            }
6. Now double click on timer1 and add this code to it:
//Refresh Weather Data
            getWeather(City);
7. Now, we need the program to save the users settings.
Under the design of the form, go to the forms events, double click where it says FormClosed, and add this code to the new section:
//Save Settings
            Settings.Default.defaultCity = txtCity.Text;
            Settings.Default.intervalText = comboBoxEdit1.Text;
            Settings.Default.windowPosition = this.Location;
            Settings.Default.timerOn = timer1.Enabled;
            Settings.Default.intervalTime = delay;
            Settings.Default.Save();

Step 6: Finishing Touches

1. Form Properties: MaximizeBox and MinimizeBox need to both be False
2. SizeGrip should be set to Hide.
3. Set the icon to the provided icon.


Just to recap, here's what your code should look like:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Animaonline.WeatherAPI;
using System.Threading;
using Weather.Properties;

namespace Weather
{
    public partial class weatherForm : Form
    {
        public weatherForm()
        {
            InitializeComponent();

            //Load settings
            delay = Settings.Default.intervalTime;
            txtCity.Text = Settings.Default.defaultCity;
            this.Location = Settings.Default.windowPosition;
            comboBoxEdit1.Text = Settings.Default.intervalText;
            timer1.Enabled = Settings.Default.timerOn;

            //Get Initial Weather
            City = txtCity.Text;
            getWeather(City);
            
        }

        private void weatherForm_Load(object sender, EventArgs e)
        {

        }

        private void getWeather(string City)
        {
            try
            {
                //Get the data
                wD = WeatherAPI.GetWeather(LanguageCode.en_US, City);

                //Set image locations
                string baseURL = "http://www.google.com";
                string iconToday = baseURL + wD.iconTODAY;
                string icon = baseURL + wD.icon;
                string iconTOMORROW = baseURL + wD.iconTOMORROW;
                string iconDAY2 = baseURL + wD.iconDAY2;
                string iconDAY3 = baseURL + wD.iconDAY3;

                //Set images
                icnCurrent.ImageLocation = icon;
                icnDay2.ImageLocation = iconDAY2;
                icnDay3.ImageLocation = iconDAY3;
                icnToday.ImageLocation = iconToday;
                icnTomorrow.ImageLocation = iconTOMORROW;

                //Current Conditions
                lblCity.Text = wD.city;
                lblCurrentCond.Text = wD.condition;
                lblCurrentF.Text = "Temperature: " + wD.temp_f.ToString() + "°F";
                lblWind.Text = wD.wind_condition;

                //Day 2's Conditions
                lblDay2.Text = wD.day_of_weekDAY2;
                lblDay2Cond.Text = wD.conditionDAY2;
                lblDay2High.Text = "High:  " + wD.highDAY2.ToString() + "°F";
                lblDay2Low.Text = "Low:  " + wD.lowDAY2.ToString() + "°F";

                //Day 3's Conditions
                lblDay3.Text = wD.day_of_weekDAY3;
                lblDay3Cond.Text = wD.conditionDAY3;
                lblDay3High.Text = "High:  " + wD.highDAY3.ToString() + "°F";
                lblDay3Low.Text = "Low:  " + wD.lowDAY3.ToString() + "°F";

                //Today's Conditions
                lblToday.Text = wD.day_of_weekTODAY;
                lblTodayCond.Text = wD.conditionTODAY;
                lblTodayHigh.Text = "High:  " + wD.highTODAY.ToString() + "°F";
                lblTodayLow.Text = "Low:  " + wD.lowTODAY.ToString() + "°F";

                //Tomorrow's Conditions
                lblTomorrow.Text = wD.day_of_weekTOMORROW;
                lblTomorrowCond.Text = wD.conditionTOMORROW;
                lblTomorrowHigh.Text = "High:  " + wD.highTOMORROW.ToString() + "°F";
                lblTomorrowLow.Text = "Low:  " + wD.lowTOMORROW.ToString() + "°F";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void getDelay(string Selection)
        {
            //Set the delay based on User Selection
            if (Selection == "Never")
                delay = 1;
            if (Selection == "1 Minute")
                delay = 1;
            if (Selection == "2 Minutes")
                delay = 2;
            if (Selection == "5 Minutes")
                delay = 5;
            if (Selection == "10 Minute")
                delay = 10;
            if (Selection == "30 Minutes")
                delay = 30;
            if (Selection == "1 Hour")
                delay = 1 * 60;
            if (Selection == "2 Hours")
                delay = 2 * 60;
            if (Selection == "4 Hours")
                delay = 4 * 60;
            if (Selection == "Select AutoUpdate Interval")
                delay = 1;
            delay = (delay * 60000);

        }

        private void getW_Click(object sender, EventArgs e)
        {
            //Set delay from minutes to milliseconds
            getDelay(comboBoxEdit1.Text);

            //Get Weather
            City = txtCity.Text;
            getWeather(City);

            //Set timer1
            if (comboBoxEdit1.Text == "Never")
            {
                timer1.Enabled = false;
            }
            else
            {
                timer1.Interval = delay;
                timer1.Enabled = true;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //Refresh Weather Data
            getWeather(City);
        }

        private void weatherForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            //Save Settings
            Settings.Default.defaultCity = txtCity.Text;
            Settings.Default.intervalText = comboBoxEdit1.Text;
            Settings.Default.windowPosition = this.Location;
            Settings.Default.timerOn = timer1.Enabled;
            Settings.Default.intervalTime = delay;
            Settings.Default.Save();
        }
    }
}
go ahead and give it a run, it should work fine.
Posted Image

Attached Files


  • 2
Programmer (n): An organism that can turn caffeine into code.
Programming would be so much easier without all the users.

#2 Guest_Jordan_*

Guest_Jordan_*
  • Guest

Posted 02 September 2009 - 04:09 AM

Wow, very cool tutorial/project! +rep
  • 0

#3 WingedPanther73

WingedPanther73

    A spammer's worst nightmare

  • Moderator
  • 17757 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others

Posted 02 September 2009 - 01:07 PM

Very well done. +rep
  • 0

Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

My MineCraft server site: http://banishedwings.enjin.com/


#4 salmanbeg

salmanbeg

    CC Lurker

  • Just Joined
  • Pip
  • 2 posts

Posted 20 July 2014 - 04:20 AM

The code is showing Exception in the line   wD = WeatherAPI.GetWeather(LanguageCode.en_US,City);

Can anybody tell me why it is showing Exception and how to resolve it.I did everything as present in the blog but still showing exception.

Thanks in advance


  • 0

#5 BlackRabbit

BlackRabbit

    CodeCall Legend

  • Expert Member
  • PipPipPipPipPipPipPipPip
  • 3871 posts
  • Location:Argentina
  • Programming Language:C, C++, C#, PHP, JavaScript, Transact-SQL, Bash, Others
  • Learning:Java, Others

Posted 20 July 2014 - 06:52 AM

Could you paste the exception text in here? so we can check it better

 

By the way, did you add the animaonline reference to your solution?


  • 0

#6 salmanbeg

salmanbeg

    CC Lurker

  • Just Joined
  • Pip
  • 2 posts

Posted 20 July 2014 - 10:38 PM

At first i add the reference to my solution and then start coding.

By the way i am adding the exception as below:--

 

System.Xml.XmlException: 'doctype' is an unexpected token.The
expected token is 'DOCTYPE'. Line 1,position 3,
     at System.Xml.XmlTextReaderImpl.Throw(Exception e)
     at System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
     at System.Xml.XmlTextReaderImpl.ThrowUnexpectedToken(String expectedToken1,String expectedToken2)
     at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl()
     at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
     at System.Xml.XmlTextReaderImpl.Read()
     at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean  preserveWhitespace)
     at System.Xml.XmlDocument.Load(XmlReader reader)
     at System.Xml.XmlDocument.LoadXml(String xml)
     at System.Xml.XmlDocument.set_InnerXml(String value)
     at Animaonline.WeatherAPI.WeatherAPI.QUERY(LanguageCode languageCode, String    CityName )
     at Animaonline.WeatherAPI.WeatherAPI.GetWeather(LanguageCode languageCode,     String CityName,Boolean Celsius,Boolean UseGeoCode)
     at Animaonline.WeatherAPI.WeatherAPI.GetWeather(LanguageCode languageCode,    String CityName)
     at WeatherApp.Weather.getWeather(String City) in e:\\Visual Studio 2012\WeatherApp\Weather.cs:line 38
 

 

Thanks in advance.................


  • 0





Also tagged with one or more of these keywords: timer, combobox