Lab 5: Interfaces that Grow

In this lab we will focus on:

  • Parallel arrays
  • Dynamically adding content to a page
  • Refreshing a page

This lab will be due Tuesday, Apr. 17th, midnight eastern time.

Introduction

Welcome to the final Lab assignment!

In this lab we will be creating an application based on a self-checkout machine at Walmart that can "grow," or add XAML components while the program is running in response to the user's actions. The plan in this assignment is to cover the rest of the tools and techniques you may need to get your Case Study project to the finish line!

The Plan

Our application will have three sections.

On the left half of the screen, we will have two input boxes (one for item name and one for price) and an Add button.

On the right half of the screen, extending down from the top, we will display the items that the user has added to the cart along with their prices.

On the right half of the screen, aligned at the bottom, we will display the current total of the items in their cart, ignoring tax and coupons and etc.

What We'll Need

Like last time, we'll want to create a Page and a Data class. We'll only need one Page this time.

In the Data class, create two arrays and a counter:

public static string[] item_names  = new string[50];
public static double[] item_prices = new double[50];
public static int      num_items   = 0;

We'll create enough room for the user to add 50 items to their cart. Any more than that and, well, the program will crash. Correcting that potential error will be for another day.

We'll also need the counter to keep track of how much of those arrays we've actually used up. It also lets us know where the next empty "slot" is.

The Checkout Page

The checkout page should function as follows.

Button Click

Like last time, we'll need to add a x:Name to our input boxes on the left half of the screen, then double click on the Add button in our designer to automatically add a click handling method.

Inside this method, we'll want to grab the values from the input boxes and store them into the Data class, such as with:

string name = NameInput.Text;
double price = Convert.ToDouble(PriceInput.Text);
int pos = Data.num_items;
Data.item_names[pos] = name;
Data.item_prices[pos] = price;
Data.num_items += 1;
App.Current.MainWindow.Content = new CheckoutPage();

In the above example I assumed that you've set the x:Name values of your input boxes to NameInput and PriceInput respectively.

We also have to manage updating the count of the number of items in the cart.

Finally, we reload the page so that the constructor below can handle inserting those items into the UI. We could just as well load a different page that is based on that cart information, but for simplicity for this Lab we are simply "looping" one page back onto itself each time the user clicks Add.

Constructor

When the page loads, we'll want to loop through the items in the cart and add XAML components dynamically so we can see the contents of the cart. To do this, we'll need a place to insert content into.

In the last lab, we added input boxes to the design and gave them x:Name values so we could reference them in the code directly. We'll do something similar here. Add a StackPanel element to the design; align it so it takes up the right half of the page, extending from the top, almost reaching the bottom. Give the StackPanel a x:Name value. I'll use x:Name="ThePanel" in my example.

While we're at it, add a text block beneath the StackPanel, in the bottom right of the page. This is where the total will be displayed. Give it an x:Name as well.

In the last lab, we dynamically displayed the message, "Hello, username" inside of the account page's constructor. Here we'll do something similar.

In the constructor for the CheckoutPage, we'll want a for loop to loop through all of the items in the cart. Keep in mind that Data.items_name.Length will always be 50 in our example, since that's how big we made the array earlier. We'll want to use Data.num_items as our cutoff point, such as:

for (int i=0; i < Data.num_items; ++i){
    // ...
}

Next, we'll want to use the data for the ith item's name and price to create a line of text, storing this text inside of a dynamically generated text block:

for (int i=0; i < Data.num_items; ++i){
    TextBlock tb = new TextBlock();
    tb.Text = Data.item_name[i] + ": " + Data.item_price[i];
    // ...
}

Finally, we'll need to add that line of text to our StackPanel:

for (int i=0; i < Data.num_items; ++i){
    TextBlock tb = new TextBlock();
    tb.Text = Data.item_name[i] + ": " + Data.item_price[i];
    ThePanel.Children.Add(tb);
}

This will handle dynamically generating the list of items in the cart. Each time the loop is run, it creates a new instance of a TextBlock object, sets its text content based on the data in the cart, and then adds it to the page.

Finally, all that is left to do after this loop is to calculate the total of the items in Data.item_prices and display that value in the text block for the total at the bottom right of the UI.

Grading and Submission Instructions

To submit, write your responses to the following questions in a Word document, then upload it to Blackboard under this week's folder in Current Assignments.

Labs are due two weeks from when they are assigned, on Sunday at 11:59pm eastern time.

Labs are each worth 5% of your final grade. Scoring on your submission will be based on the following rubric:

0% - Student does not submit on time or submits plagiarized or unacceptable work. Double check that you have attached the right file, as usually students get zeros because they upload a previous week's Lab by accident.

1% - Student answers less than half of the questions with sufficient or accurate responses. Make sure that you are leaving yourself enough time to complete the Lab each week, as usually students submit incomplete work because they were rushed at the last minute.

3% - Student answers almost all questions with sufficient and accurate responses. If you encounter a problem or have a question about one of the questions, be sure to post in Ask the Instructor well before 24 hours before the due date, then continue to attempt to resolve the issue on your own while you wait for a reply.

5% - Great job, maximum points! The student answers all questions accurately and sufficiently, demonstrating the best of their ability.

Note, because Labs span two weeks' worth of reading, it is recommended to go through the Lab twice, once after the first reading where you answer everything that you can, then again after the second reading where you answer everything else.

Questions

  1. Get the Checkout example above to work. Demonstrate your answer with screenshots of each of your file's C# and screenshots of each stage of your program running.
  2. For each screen of your case study application, what "lists" are might need to be displayed whose content and length is dependant on the user? If none come to mind, is there anyway that your application could benefit from displaying a list of its recent outputs? Why or why not? Explain.
  3. Do some research on the Microsoft C# WPF documentation pages and/or Stackoverflow. How would you dynamically add a button to a WPF application and set its onclick event handler?
  4. What obstacles are you facing or do you foresee facing in completing your Case Study Project? Where could you reach out for help in overcoming these obstacles?