0.5 First Day Assignment

Overview

Continue your completed 0.4 First Day application. Keep the shopping-list save and load features, replace the window layout, and add a button that retrieves weather using longitude and latitude.

Goal: Request information from an online service and display the result in your application.

Acceptance Criteria

  • The existing student, breakfast, backpack, and clothing controls still work.
  • Save Shopping List and Load Shopping List still work as they did in 0.4.
  • The window uses the supplied XAML layout.
  • Clicking Load weather requests weather for the entered coordinates and displays the returned JSON forecast in the browser area.
  • A failed weather request displays an error message in the browser area.
  • The completed solution is submitted through the Feedback System, and its URL is submitted to Canvas.
Instructions
1.Open Your Existing Solution
A Back up and open the solution
1 Close Visual Studio if the solution is open
2 Back up the completed 0.4 solution folder

Name the backup First Day 0.4 Backup LastName.

3 Open LastName.sln from your original working folder

Keep the working folder and solution names unchanged.

4 Run the application and verify the existing controls work

Include Save Shopping List and Load Shopping List. Fix any existing errors before continuing.

5 Close the application before editing
2.Explore the Weather Service
A Explore the Open-Meteo documentation
1 Open the Open-Meteo website in your regular web browser
https://open-meteo.com/en/docs

Open-Meteo provides weather data through an API: an interface that lets an application request information from an online service. Its documentation lets you explore locations, weather variables, and the URL used to request data.

2 Find the latitude and longitude fields

Latitude describes a location north or south of the equator. Longitude describes a location east or west of the prime meridian. Negative values represent south or west. Our window places longitude first, so read each label carefully.

3 Explore the available weather variables

Explore the daily precipitation variables. This assignment requests one day of precipitation hours, maximum precipitation probability, and totals for precipitation, showers, rain, and snowfall. The URL also specifies unit preferences. Read the returned daily_units values to identify the units for each result. The service returns JSON: text containing named values and lists. Your application will display that response directly.

3.Replace the Window Layout
A Replace the existing XAML
1 Open FirstDayScenario/MainWindow.xaml

Switch to the XAML source view.

2 Select all existing XAML and paste the following XAML over it

Replace the entire contents of MainWindow.xaml, from the opening Window tag through the closing Window tag. Do not paste this into MainWindow.xaml.cs. Keep your existing C# methods.

MainWindow.xaml — replace all existing XAML
<Window x:Class="FirstDayScenario.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FirstDayScenario"
        mc:Ignorable="d"
        Title="MainWindow" Height="700" Width="435">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Top">
            <Button x:Name="newStudentButton" Content="New student" Width="125" Margin="5" Click="NewStudentButton_Click" />
            <Button x:Name="haveBreakfastButton" Content="Have breakfast" Width="125" Margin="5" Click="HaveBreakfastButton_Click" />
            <Button x:Name="fillBackpackButton" Content="Fill backpack" Width="125" Margin="5" Click="FillBackpackButton_Click" />
        </StackPanel>
        <StackPanel Grid.Row="1">
            <TextBlock Text="Weather" FontWeight="Bold" Margin="5" />
            <StackPanel Orientation="Horizontal">
                <CheckBox x:Name="rainCheckBox" Content="It is raining" Width="125" Margin="5" HorizontalAlignment="Left" />
                <Button x:Name="chooseClothingButton" Content="Choose clothing" Width="125" Margin="5" Click="ChooseClothingButton_Click" />
            </StackPanel>
        </StackPanel>
        <StackPanel Grid.Row="4" HorizontalAlignment="Stretch" VerticalAlignment="Top">
            <TextBlock Text="School Shopping List" FontWeight="Bold" Margin="5" />
            <TextBox x:Name="shoppingListTextBox" Height="90" Margin="5" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" />
            <StackPanel Orientation="Horizontal">
                <Button x:Name="saveShoppingListButton" Width="125" Content="Save shopping list" Margin="5" Click="SaveShoppingListButton_Click" />
                <Button x:Name="loadShoppingListButton" Width="125" Content="Load shopping list" Margin="5" Click="LoadShoppingListButton_Click" />
            </StackPanel>
        </StackPanel>
        <StackPanel Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Top">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Longitude:" Width="125" Margin="5,5,5,0"/>
                <TextBlock Text="Latitude:" Width="125" Margin="5,5,5,0"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBox x:Name="longitudeTextBox" Width="125" Margin="5"/>
                <TextBox x:Name="latitudeTextBox" Width="125" Margin="5"/>
                <Button x:Name="loadWeatherButton" HorizontalAlignment="Left" Content="Load weather" Width="125" Margin="5" Click="LoadWeatherButton_Click" />
            </StackPanel>
            <Border Height="125" BorderThickness="1" BorderBrush="Black">
                <WebBrowser x:Name="BrowserControl"/>
            </Border>
        </StackPanel>
        <TextBox Grid.Row="6" x:Name="textOutput" HorizontalAlignment="Stretch" Height="90" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" />
    </Grid>
</Window>
3 Save MainWindow.xaml

The new LoadWeatherButton_Click method has not been created yet. Complete the next task before building or running the application.

B Check the existing event-handler connections
1 Compare the existing Click values with your C# method names

Capitalization matters. Keep the existing SaveShoppingListButton_Click and LoadShoppingListButton_Click methods and their code from 0.4. The control names now begin with lowercase letters: saveShoppingListButton and loadShoppingListButton. Update any C# references to the old control names if you used them; the event-handler method names still begin with uppercase letters.

4.Load Weather and Check the Application
A Create the Load weather event handler
1 Double-click the Load weather button in the XAML designer

Open the Design view of MainWindow.xaml and double-click Load weather. Visual Studio creates the Click event handler and opens MainWindow.xaml.cs. The method must be named LoadWeatherButton_Click, matching the supplied XAML exactly. If the method already exists, double-clicking opens it; do not add a duplicate.

2 Add the HTTP using statement if it is missing

Keep the existing using statements, including System.IO from 0.4. Add this line with the other using statements at the top of MainWindow.xaml.cs.

MainWindow.xaml.cs — using statements
using System.Net.Http;

The code below spells out the full names of several types. You do not need a JSON parsing package because the application displays the response as text.

3 Add the HTTP client field inside the MainWindow class

Place this field immediately after the existing Student field and before the constructor. It belongs inside the MainWindow class, outside all methods. Keep the existing Breakfast and Student fields and Feedback attributes.

MainWindow.xaml.cs — add below the Student field
private static readonly System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();

This client sends requests to the weather service and is reused each time you click Load weather.

4 Add GetForecastAsync below the client field

Paste this complete method after the client field and before the constructor's documentation comment. Do not place it inside the constructor or another method.

MainWindow.xaml.cs — add GetForecastAsync
private async System.Threading.Tasks.Task<string> GetForecastAsync()
{
    string url = $"https://api.open-meteo.com/v1/forecast?latitude={latitudeTextBox.Text}&longitude={longitudeTextBox.Text}&daily=precipitation_hours,precipitation_probability_max,precipitation_sum,showers_sum,rain_sum,snowfall_sum&forecast_days=1&wind_speed_unit=mph&temperature_unit=fahrenheit&precipitation_unit=inch";

    return await client.GetStringAsync(url);
}

The URL uses the text from the two coordinate TextBoxes. The latitude parameter must read latitudeTextBox.Text, and the longitude parameter must read longitudeTextBox.Text. Keep the URL on one line. GetStringAsync retrieves the response as a string. The async and await keywords allow the application to wait for the response without blocking the window.

5 Replace only the generated LoadWeatherButton_Click method with this method

Include the method declaration and braces below. Notice the async keyword in the declaration. Do not paste a method inside another method, and do not replace the entire MainWindow class. Keep the constructor and every event handler from 0.4.

MainWindow.xaml.cs — LoadWeatherButton_Click
private async void LoadWeatherButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    try
    {
        string json = await GetForecastAsync();

        string html = "<html><head>"
            + "<meta charset=\"utf-8\">"
            + "</head><body>"
            + "<pre style=\"white-space:pre-wrap;word-wrap:break-word;\">"
            + System.Net.WebUtility.HtmlEncode(json)
            + "</pre></body></html>";

        BrowserControl.NavigateToString(html);
    }
    catch (System.Exception ex)
    {
        BrowserControl.NavigateToString(
            "<html><body><h1>Unable to retrieve the forecast</h1><p>"
            + System.Net.WebUtility.HtmlEncode(ex.Message)
            + "</p></body></html>");
    }
}

The event handler calls GetForecastAsync and stores the response in json. HtmlEncode makes the response safe to display as text inside an HTML page. NavigateToString displays that page in BrowserControl. If the request fails, the catch block displays an error in the same browser area. Weather loading does not change textOutput or the rain checkbox.

6 Save all files and build the solution

Correct errors before continuing. If a Click handler is missing, double-click its button in the designer to create or open the handler. Restore its implementation from your 0.4 backup when needed; an empty handler will not perform the previous behavior.

B Check Your Work: Weather and all existing buttons
1 Run the application
2 Click New student

Verify that Nou Xiong, the student ID, energy level, and hungry status appear. Click New student before Have breakfast or Fill backpack so that a Student object exists.

3 Click Have breakfast

Verify that the output describes the breakfast and updated energy level and hungry status.

4 Click Fill backpack

Verify that its previous behavior still works.

5 Check Choose clothing with the rain checkbox selected and cleared

Verify both clothing outcomes from the previous assignment. Loading weather does not automatically change this checkbox.

6 Check the Save Shopping List button from the previous assignment

Type Notebook and Pens, one per line, into the shopping-list TextBox. Click Save shopping list. Verify that the output says Shopping list saved..

7 Check the Load Shopping List button from the previous assignment

Close and restart the application. Verify that the shopping-list TextBox starts empty. Click Load shopping list. Notebook and Pens should reappear, and the output should say Shopping list loaded.. Clear the TextBox and click Load shopping list again without saving; the same items should return.

8 Enter the example coordinates

Type -87.6298 in Longitude and 41.8781 in Latitude. Use a period for the decimal separator. These coordinates identify a location in Chicago.

9 Click Load weather and inspect the result

With an internet connection, the browser area should display the JSON response. Look for daily_units, daily, and the requested precipitation fields. Scroll within the browser area if needed. The values change over time; no particular forecast value is required. The textOutput area keeps its previous message.

10 Enter an invalid coordinate and click Load weather

Keep the example longitude and change Latitude to 100. Click Load weather. The browser area should display Unable to retrieve the forecast with an error message because the request contains an invalid latitude. Restore Latitude to 41.8781 and verify that the JSON response loads again.

11 Close the application
Submission
5.Final Check and Submit
A Complete the final technical check
1 Build the solution and correct any build errors
2 Verify that all checks in Step 4B pass

Include both Save Shopping List and Load Shopping List, as well as Load weather.

B Zip the solution
1 Close Visual Studio
2 Create a ZIP of the entire LastName solution folder
3 Open the ZIP and confirm the solution and project are present

Verify that LastName.sln and the FirstDayScenario project folder are included.

C Submit to the Feedback System
1 Open the Feedback System and select First Day 0.5
2 Upload the zipped Visual Studio solution
3 Review the results and correct any required issues

Resubmit an updated ZIP when needed.

D Submit the Feedback System URL to Canvas
1 Copy the Feedback System submission URL
2 Open the 0.5 First Day Assignment in Canvas
3 Submit the Feedback System URL as your Canvas submission