Quantity Data Binding

Right now when a new item is added to one of the item lists it has a default quantity of one. On the Buy list you can increase an item’s quantity in increments of one (you might want to buy three loaves of bread or two dozen eggs). I decided that I wanted that when you’re adding an item to the Buy list on the Add Item screen I wanted to let you specify a quantity greater than one.

Add-Item-Buy-0  Add-Item-Add-0To do this I added two new controls to AddItemPage.xaml, a quantity Label and a quantity Slider, and grouped these controls into StackLayout with an horizontal orientation.

<StackLayout x:Name="quantityControl" Orientation="Horizontal"
	HorizontalOptions="Center" VerticalOptions="Center"
	IsVisible="false">
		<Label x:Name="quantityLabel" VerticalOptions="Center"/>
		<Slider x:Name="quantitySlider" Maximum="4" Minimum="1"/>
</StackLayout>

The slider implementation was pretty straightforward since I merely had to set a minimum and maximum value for the slider value. There was one interesting bug–I kept getting an “Invalid value for slider” error message when trying to display the screen. It turns out it’s a known issue, the solution being that you have to specify the maximum value before you specify the minimum value.

The label implementation was a bit more interesting. As the person moves the slider to change the quantity I wanted the current value to be displayed to the left of the slider. To do this efficiently I had to bind the label’s Text value to the the slider’s current Value.

Data binding connects the properties of two objects, the source and the target. It can be done either in code or in XAML. Since my Add Item screen was laid out using XAML I went that route.

<StackLayout x:Name="quantityControl" Orientation="Horizontal"
	HorizontalOptions="Center" VerticalOptions="Center"
	IsVisible="false">
		<Label x:Name="quantityLabel" VerticalOptions="Center"
			BindingContext="{x:Reference Name=quantitySlider}"
			Text="{Binding Path=Value, StringFormat='{0:F0} Quantity'}"/>
		<Slider x:Name="quantitySlider" Maximum="4" Minimum="1"/>
</StackLayout>

The first thing was to use the BindingContext attribute to tell the target (Label) the source (Slider) of its data. You do this by calling out Slider’s x:Name in Label’s x:Reference attribute (I could have just written “x:Reference quantitySlider” since x:Reference’s ContentProperty is defined as Name but I wanted to be explicit and went with the full “x:Reference Name=quantitySlider”).

The second step is to have Label’s Text display the Slider’s Value by using the Binding attribute. Again, I could have written “Binding Value” instead of “Binding Path=Value” since Binding has a ContentProperty of Path but I wanted to be explicit so I went with the full “Binding Path=Value” (I might have to come back and read this code one of the days).

Add-Item-Buy-0-4

I had to make some changes to the OnDestinationgSwitchToggled handler to show or hide the Label and Slider depending on the position of the destination switch.

void OnDestinationSwitchToggled(object sender, EventArgs args)
{
	if (destinationSwitch.IsToggled == true) {
		destinationLabel.Text = "Save to Add list";
		quantityControl.IsVisible = false;
		addToBuyList = false;
	} else {
		destinationLabel.Text = "Save to Buy list";
		quantityControl.IsVisible = true;
		addToBuyList = true;
	}
}

Which you can see here.

Add-Item-Buy-0  Add-Item-Add-0

And finally a small change in the OnSaveClicked method where the new item is created before adding it to the list.

Previously I was just passing in the item name and a flag to tell which list to add the item to (the quantity defaulted to one if it wasn’t specified).

Item newItem = new Item(itemName, addToBuyList);

Now I had to make sure to pass the quantity slider’s value in as a third parameter.

Item newItem = new Item(itemName, addToBuyList, (int)quantitySlider.Value);

Some helpful links:

This entry was posted in Side Projects, Software Development and tagged , , , , . Bookmark the permalink.