# Milestone 6 Requirements

### General requirements:

• You will need to follow the style laid out in the C# Coding Conventions

• You will need to update your UML to reflect your current code

• You will need to update your tests to reflect changes to your Data project

### Assignment requirements:

• Implement the INotifyPropertyChanged interface on all menu items

• Override the default ToString() method on all Entrees, Sides, Drinks, and Treats to supply a descriptive name for the item

• Write tests for all additions to the Data project

• Use data binding to modify the object you are customizing through the controls you have added to your customization screen

• Update your UML Class Diagrams for:

• Data Library
• Point of Sale

(You don’t need to create a UML of your test project, though you can if you like)

### Purpose:

This assignment is intended to familiarize you with the concept of data binding, especially:

1. How it depends on PropertyChanged events to work.
2. How data binding is expressed in XAML (the Binding syntax)
3. How the DataContext property in WPF controls can be used to share a bound object

Additionally, this assignment should give you plenty of practice making WPF controls functional. This is also where your projects will really start to diverge from each other depending on the implementation route you choose to follow.

### Assignment Details

#### Implementing INotifyPropertyChanged

Most of this assignment is centered around the implementation of the INotifyPropertyChanged interface. This needs to be implemented on every menu item. Implementing the interface requires you to declare an event of type PropertyChangedEventHandler named PropertyChanged. Doing this much satisfies the letter of the INotifyPropertyChanged interface, but not the intent.

To satisfy the intent, you should also invoke any event listeners registered with your PropertyChanged event handler when one of the properties of the object changes, with the details about that change. You must do this for ALL properties that can change in your menu item classes (Hint: you can skip properties like the FriedPie.Price, which cannot change).

To verify that you have correctly implemented these properties, you need to write additional tests to check that the property does, indeed change. The PropertyChange Assertion we discussed in the testing chapter is used for this purpose. These tests should be placed in the unit test class corresponding to the menu item being tested.

Here is an example using the FriedPie:

[Theory]
[InlineData(PieFilling.Peach)]
[InlineData(PieFilling.Apricot)]
[InlineData(PieFilling.Pineapple)]
[InlineData(PieFilling.Blueberry)]
[InlineData(PieFilling.Apple)]
[InlineData(PieFilling.Pecan)]
public void ChangingFlavorShouldNotifyOfChange(PieFilling flavor)
{
var pie = new FriedPie();
Assert.PropertyChanged(pie, "Flavor", ()=>{
pie.Flavor = flavor;
});
}


Additionally, it is a good idea to test that the menu item classes implements the INotifyPropertyChanged interface. This can be accomplished with the IsAssignableFrom<T>(object obj) Type Assertion, i.e.:

public void FriedPieShouldImplementINotifyChanged()
{
var pie = new FriedPie();
Assert.IsAssignableFrom<INotifyPropertyChanged>(pie);
}


#### Override ToString()

Every C# object has a ToString() method that gives a textual representation of the object. This is also used by WPF when you bind an object to a text control, like a TextBox. The default behavior of ToString() is to give the fully-qualified name of the class, i.e. for a FriedPie it would return "FriedPiper.Data.FriedPie". It is therefore a good idea to override this behavior in our data classes to use a more human-readable name, i.e. "Fried Cherry Pie". The string returned should be the same as that provided by your Name property.

#### Testing ToString() Implementation

You should add a test method named ToStringShouldReturnExpectedValue() to each of your Entree, Side, Drink, and Treat unit test classes to verify your ToString() implementation returns the expected value. It may or may not need parameters (i.e. size, flavor), depending on the class in question.

#### Binding Items for Customization

When you open a customization screen for a menu item, you need to also bind the object you are customizing. The customization control’s DataContext should be set to the object you want to customize.

The exact way in which you will do this depends on your implementation, but it will likely occur in your event listener for when a menu item is clicked, or in a helper method. Your process should be something like:

1. Create an instance of the appropriate Entree, Side, Drink, or Treat (based on which button was clicked)
2. Bind that instance as the DataContext of the corresponding customization control instance
3. Display that customization control instance in the MainWindow, replacing or covering up the MenuItemSelectionControl

Since the event you are listening for happens in the MenuItemSelectionControl but the displaying must happen in the MainWindow, you must decide which of these two locations you want to host the event listener. If you choose the MainWindow you will be using a Routed Event, i.e. Button.Click. If you choose the MenuItemsSelectionControl you will need to climb the Elements tree to reach the MainWindow.

#### Binding Customization Controls

Once you know you have your menu item classes (your entrees, sides, drinks, and treats) ready, you can bind their properties to the controls you have created in your customization screens. Since you have set the screen’s DataContext to be a new instance of that item (in the previous requirement), these controls will now directly modify the bound menu item object.

With many controls, verifying your binding is working correctly may be difficult (as the control behaves the same either way). Using breakpoints, or supplying an initialized object with properties changed from their default to the binding are two ways of verifying. Alternatively, you can bind the same property to a display-only <TextBlock> in a summary section. This verification will become much easier when we add order tracking in the next milestone.

Finally, update your UML to reflect the current state of your Data and PointOfSale projects.

The INotifyPropertyInterface can be added like so:

Because this is a realization relationship, you will also need to add the event to your class boxes. It should be placed in the second box (with your properties) and use the event stereotype, i.e.:

+PropertyChanged:PropertyChangedEventHandler <<event>>


Also, remember that any event listeners you have defined in your code behind in the PointOfSale project must be represented in your UML. Also, any properties you have given a x:Name attribute in your XAML, i.e.:

<MainWindow>
<Border x:Name="SwitchBorder">
</Border>
</MainWindow>


Are public properties and should therefore show up in your UML, i.e.:

+SwitchBorder:Border <<get, set>>


You do not need to show components defined in the XAML that do not have a x:Name property.

Note: You do not need to create a UML diagram of your DataTest project, though you can if you want.

## Submitting the Assignment

Once your project is complete, merge your feature branch back into the main branch and create a release tagged v0.6.0 with name "Milestone 6". Copy the URL for the release page and submit it to the Canvas assignment.