Filtering Sample Data with Linq

After creating an Item class for individual shopping list items.

public class Item
{
	public string Name { get; set; }
	public bool Buy { get; set; }

	public Item(string name, bool buy) {
		this.Name = name;
		this.Buy = buy;
	}
}

I used it to create a set of sample data

public List<Item> GetSampleData() {
	return new List<Item> {
		new Item("Milk", true),
		new Item("Eggs", true),
		new Item("Carrots", true),
		new Item("Raisins", false),
		new Item("Bread", false)
	};
}

The intention was to keep a single list for all items in the app but only display the items that needed to be bought (Item.Buy == true) in the Buy list and the items that could be added (Item.Buy == false) in the Add list.

GetSampleData is called in the App constructor and the list that’s returned is stored in the Properties Dictionary.

(Calling GetSampleData in the app’s OnStart event threw a runtime exception because the constructor created the two tab pages and the dictionary wasn’t populated properly at that time when each page’s constructor was called).

public App()
{
	allItems = GetSampleData();
	this.Properties["Items"] = allItems;

	// The root page of your application
	MainPage = new TabPage {
		Children = { new BuyPage(), new AddPage() }
	};
}

The next step was to display the sample data on the individual pages, filtering on the Buy property. Here’s all the code for BuyPage.

public class BuyPage : ContentPage
{
	private List<Item> allItems;
	private IEnumerable<Item> buyItems;
	private ListView buyView;

	public BuyPage()
	{
		Title = "Buy";
		Icon = "19-checkmark.png";

		if (Application.Current.Properties.ContainsKey("Items")) {
			allItems = (List<Item>)Application.Current.Properties["Items"];
			buyItems = allItems.Where(item => item.Buy != false);
		}

		buyView = new ListView {
			RowHeight = 60,
			ItemsSource = buyItems,
			ItemTemplate = new DataTemplate(typeof(TextCell))
		};

		buyView.ItemTemplate.SetBinding(TextCell.TextProperty, "Name");

		Content = new StackLayout {
			VerticalOptions = LayoutOptions.FillAndExpand,
			Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0),
			Children = { buyView }
		};
	}
}

At the top of the class are the two Lists, allItems and buyItems, as well as the ListView which will display the contents of buyItems.

private List<Item> allItems;
private IEnumerable<Item> buyItems;
private ListView buyView;

The list of all the items is read from the Properties Dictionary by key, cast to List, and stored in allItems (the dictionary stores everything as objects so you need to cast everything before using it). The Linq extension method Where is used to filter the allItems list, storing only the items where Buy is true in the buyItems list.

if (Application.Current.Properties.ContainsKey("Items")) {
	allItems = (List<Item>)Application.Current.Properties["Items"];
	buyItems = allItems.Where(item => item.Buy != false);
}

The remaining code in the BuyPage constructor creates a new ListView, setting its the filtered buyItems list as its data source and the individual list items as TextCells, binds each list item to the Item.Name property so the name of the item is displayed onscreen, and, finally, adds the ListView to a StackLayout.

buyView = new ListView {
	RowHeight = 60,
	ItemsSource = buyItems,
	ItemTemplate = new DataTemplate(typeof(TextCell))
};

buyView.ItemTemplate.SetBinding(TextCell.TextProperty, "Name");

Content = new StackLayout {
	VerticalOptions = LayoutOptions.FillAndExpand,
	Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0),
	Children = { buyView }
};

The result is that the appropriate items are displayed on the appropriate page.

IMG_0991  IMG_0992

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