A ContentPage Wrapped in a TabPage Wrapped in a NavigationPage

A redesign adds a NavigationBar at the top so the application name can be displayed along with a Settings button on the Buy page and an Add button on the Add page.

Viand-Mockup-2

A ContentPage doesn’t have a NavigationBar at the top so the solution was to “wrap” the TabPage in a NavigationPage. The code changed from this:

public class App : Application
{
    public App()
    {
        MainPage = new TabPage {
           Children = { new BuyPage(), new AddPage() }
        };
    }
 }

To this:

public class App : Application
{
    public App()
    {
        MainPage = new NavigationPage(new TabPage());
    }
 }

Adding BuyPage and AddPage as children was moved into the TabPage constructor.

public class TabPage : TabbedPage
{
	public TabPage()
	{
		Title = "Viand";
		Children.Add(new BuyPage());
		Children.Add(new AddPage());
	}
}

Buttons are added to a NavigationBar by adding a new ToolbarItem to each ContentPage’s ToolbarItems collection.

// BuyPage
ToolbarItems.Add(new ToolbarItem {
	Text = "Settings",
	Icon = "106-sliders.png",
	Order = ToolbarItemOrder.Default,
	Command = new Command(() => Navigation.PushAsync(new SettingsPage()))
});

// Add Page
ToolbarItems.Add(new ToolbarItem {
	Text = "Add",
	Icon = "187-pencil.png",
	Order = ToolbarItemOrder.Default
});

Specifying Text and not an Icon for a ToolbarItem displays the text as an iOS 7 button.

Viand-Toolbar-No-Icons

Specifying an Icon suppresses the ToolbarItem text.

Viand-Toolbar-Icons

For now I’m going to leave the toolbar buttons as text–I like the way they look (I’m also using the pencil icon in the Add tab).

Posted in Side Projects, Software Development | Tagged , , | Leave a comment

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

Posted in Side Projects, Software Development | Tagged , , , | Leave a comment

Git Commands I’ve Used

I’ve a lot of experience as a software developer using centralized version control systems like Subversion, Team Foundation, and SourceSafe. For the past month and a half I’ve been using Git, a distributed version control system for my side projects (in conjunction with BitBucket and possible GitHub as remote repositories).

I’ve been using the excellent Getting Git Right tutorial by Atlasssian to get started. This post is a record of the Git commands I’ve been using at the command line on a regular basis, which I’ll update at regular intervals (I want to learn at the command line first before using a GUI to hide the complexity).

git init
git clone

git status
git log

git add
git commit
git commit --amend

git branch // lists all branches in rep
git branch <branch> // creates new branch
git checkout // switches to new branch

git push
git remote

I also figured out how to push a local git repository to Bitbucket at the command line (prior to this I created repos in Bitbucket and pulled them down to my local machine).

Again the Atlasssian web site was extremely helpful, I found several good pages on how to import code from an existing project, using the SSH protocol with Bitbucket, setting up SSH for Git and Mercurial, and rectifying SSH Authenticity errors.

Posted in Software Development | Tagged | Leave a comment

Avoiding Status Bar Overlap with StackLayout Padding

The StackLayout positions child elements in a single line either vertically  or horizontally, setting child bounds automatically. On iOS 7 onwards this means that the top child element in a StackLayout will overlay the status bar.

Viand-Tabbed-Screen-1a

In order to get around this you can use the StackLayout’s Padding property.

Content = new StackLayout {
    Padding = new Thickness(0, 20, 0, 0),
    Children = {
        new Label { Text = "Hello BuyLayout" }
    }
};

Which moves the child elements down a bit.

Viand-Tabbed-Screen-2

This modification affects both iOS and Android it needs to be platform-specific.

Content = new StackLayout {
    Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 20, 0),
    Children = {
        new Label { Text = "Hello BuyLayout" }
    }
};

Device. OnPlatform is a generic method that can be used to provide platform-specific has three optional parameters. It has three optional parameters: iOS, Android, and WinPhone (more Xamarin.Forms platform tweaks here).

In the code example above I’m providing a Top padding value for iOS of 20 but leaving Android and Windows Phone at 0. The screenshots below show the child element correctly positioned on each platform.

Viand-Tabbed-Screen-3

Posted in Side Projects, Software Development | Tagged , , , | Leave a comment

Leonard Nimoy – 1931 to 2015

spock-the-cageWhen my wife messaged me that Leonard Nimoy had died I was shocked and sad but not surprised (they’re all getting up there in years). Of all the Star Treks the original series, the one I used to watch at 6 p.m. after school on channel 11, is still my favorite.

Star Trek (NBC)   TV Series1966-1969Shown: Leonard NimoyI stopped by a colleague’s cube at work to tell him the news (his Next Generation coffee cup indicated his fandom). He had already heard the news but we spent a brief time with another coworker who was also a fan, talking about our favorites episodes, our favorite Star Trek series, and science fiction television shows in general.

The-Wrath-of-Khan-mr-spock-23640452-1405-776After getting William Shatner’s autograph on my 1977 Star Trek Blueprints at this years RI ComicCon I had hoped to get the autographs of the surviving cast members at subsequent events. I’ll still try to get Nichelle Nichols, Walter Koenig, and George Takei but will regret never having a chance to tell Leonard Nimoy how much I enjoyed his work over the years.

I’ll end with clips from two excellent Original Series episodes featuring Spock – Amok Time and This Side of Paradise.

Posted in Other | Tagged , | Leave a comment

Grocery Shopping with Xamarin.Forms

My wife and I have tried using several iPhone list programs over the past year to create a shared grocery list so either of us could pick up items that we needed when one of us happened to be at the store.

We first tried Apple’s Reminders app since it was already on our phones and it allowed the sharing of lists via iCloud. It worked well at first when the list was small but completed items weren’t alphabetized automatically so we end up with duplicates in our list–it was quicker for my wife and I to add a new item to the list rather than spend time searching through an ever-growing list of unalphabetized items to find what you wanted to buy. We switched to Wanderlust, a more generic list program, that allows sharing but still doesn’t allow alphabetizing of bought, i.e. completed items (I don’t know why we chose that one, I guess I happened to have it on my iPhone and at first glance it seemed like it would solve the problem–lesson learned).

So I’m decided to write my own iPhone program using the latest version of Xamarin Platform and teach myself Xamarin.Forms.

The app will be relatively simple–two lists in a tabbed interface. The Buy list contains the items you want to purchase, the Add list contains the items you purchased previously (you can add items to each list). When you purchase something on the Buy list you swipe right on that item to remove it from the Buy list and automatically place it in the Add list. On the Add list you swipe left on an item to add it to the Buy list or swipe right on an item to remove it from the Add list entirely. The Add list is automatically alphabetized and has an index on the right so you can quickly get to the items you want to add. Right now I don’t know how I’ll handle syncing between devices, probably iCloud, Dropbox, or Azure.

Viand-Mockup-1

A Blank App (Xamarin.Forms Portable) solution contains three projects–one for your common code and one for each platform. In the solution below the common project is Viand and the Android and iOS projects are Viand.Droid and Viand.iOS, respectively.

Viand-Solution-1

When I was last building Android and iOS apps with Xamarin for Trimble you could share your controller, model, and view model code across platforms but your views, the actual screens the user interacted with, had to be coded specifically for each platform. Xamarin.Forms promises “native UIs for iOS, Android, and Windows Phone from a single, shared C# codebase.”

Out of the box Xamarin.Forms comes with a collection of pages, layouts, and controls. The grocery list app calls for a TabbedPage with two ContentPages, one for each tab. Each ContentPage will contain a single StackLayout that contains a single ListView.

Viand-Page-Layout-Control-Hierarchy

The TabbedPage page and the ContentPages are created by right-clicking the “common” project, selecting Add -> New File, and then choosing Forms Content Page. In keeping with the Xamarin.Forms hierarchy I’ve name the page and the layouts appropriately.

Viand-Solution-2

I changed TabPage so it inherits from TabbedPage instead of ContentPage and replaced the default code that was in the its constructor with a single line that set it’s Title property.

public class TabPage : TabbedPage
{
    public TabPage()
    {
       this.Title = "Viand";
    }
}

I left the default code in BuyPage but added two lines to set its Title and Icon properties, both of which will be used by TabPage.

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

        Content = new StackLayout {
            Children = {
                new Label { Text = "Hello BuyLayout" }
            }
        };
    }
}

I did the same with AddPage.

public class AddPage : ContentPage
{
    public AddLayout()
    {
        Title = "Add";
        Icon = "13-plus.png";

        Content = new StackLayout {
            Children = {
                new Label { Text = "Hello AddLayout" }
            }
        };
    }
}

The final step is to modify the App class to set the MainPage to my TabPage “container” and add the two pages as children (the App class can be found in the Viand.cs file located in the Viand project.)

public class App : Application
{
    public App()
    {
        MainPage = new TabPage {
           Children = { new BuyPage(), new AddPage() }
        };
    }
 }

Selecting each project as the startup project and running it in its respective emulator shows how native iPhone (left) and Android (right) user interfaces are created easily from a single codebase.

Viand-Tabbed-Screen-1

Very cool. Next steps, adding the TableViews to each layout, creating a data structure to handle Buy and Add list items, and implementing the swiping actions.

 

 

Posted in Side Projects, Software Development | Tagged , , , | Leave a comment

The Maturity Climb

maturity_climb1

Posted in Other | Tagged | Leave a comment