Toolroom Tech Blog

Devlopers Digest

Fix by Rewrite for XAML ScrollViewer issue

How to fix strange scrolling behavior within a Windows Phone Pivot by rewriting a few lines of XAML 1:1 :)

Yesterday I had the strangest XAML behaviour ever ... I have to share this!

The issue 

In a Windows Phone app I have this object tree in my ApplicationPage, where each View contains a ScrollViewer with simple Grid content - nothing special.

<Grid x:Name="LayoutRoot">
	<controls:Pivot Title="{Binding PageTitle}">
		<controls:PivotItem Header="Page 1">
			<Grid>
				<Views:ItemOneView DataContext="{Binding Data}"/>
			</Grid>
		</controls:PivotItem>
		<controls:PivotItem Header="Page 2">
			<Grid>
				<Views:ItemTwoView DataContext="{Binding Data}"/>
			</Grid>
		</controls:PivotItem>
		<controls:PivotItem Header="Page 3">
			<Grid>
				<Views:ItemThreeView DataContext="{Binding Data}"/>
			</Grid>
		</controls:PivotItem>
	</controls:Pivot>
</Grid>

The issue was, that the runtime didn't allow me to scroll down to hidden content of ItemTwoView. The scrollbar didn't come up and altough I saw the content while scrolling, it moved back to the original position when I stopped.

The fix

After hours of debugging, I just rewrote the 5 lines from <controls:PivotItem Header="Page 2"> to </controls:PivotItem> exactly 1:1. And it worked!

I really didn't believe it ... so I pushed undo and had the behavior again, although the code didn't change. Hidden characters? Encoding issue? Bug? Don't know.

Hex string to Color conversion on Windows Phone 7.x

Function to convert a hex string to a Color

In a Windows Phone 7 project I recently needed a function that does the work of System.Drawing.ColorTranslator.FromHtml(string color). Therefore I wrote this little extension method.

It deals with RGB and ARGB input values, with or without the leading hash.

public static Color FromHtml(this string s)
{
	// Check fore a valid code (RGB = 6 chars, ARGB = 8 chars)
	var regex = new Regex(@"^[A-Fa-f0-9]*$");
	if (s == null || ((s = s.Trim().TrimStart('#')).Length != 6 && s.Length != 8) || !regex.IsMatch(s))
		return Colors.White;

	int index = 0;

	// If the color length is 8, the first 2 chars contain the alpha part
	byte a = 255;
	if (s.Length == 8) 
	{
		a = Convert.ToByte(s.Substring(0, 2), 16);
		index += 2;
	}

	// Get R value
	byte r = Convert.ToByte(s.Substring(index, 2), 16);
	index += 2;
	// Get G value
	byte g = Convert.ToByte(s.Substring(index, 2), 16);
	index += 2;
	// Get B value
	byte b = Convert.ToByte(s.Substring(index, 2), 16);

	return Color.FromArgb(a, r, g, b);
}

Usage:

var color1 = "#CC3333".FromHtml();

var color2 = "CC3333".FromHtml();

var color3 = "#FFCC3333".FromHtml();

Linq to Sql: Row not found or changed

Finding a way back from LINQ to SQL cuncurrency hell.

Yesterday I was trapped in concurrency hell and had no idea why.

Background

The Windows Phone App I am currently working on, synchronizes data between a local database and a REST service. When the app receives an update for a row, I select the row to be updated from the local database via LinqToSql, update its values with the data from the service and save it.

The issue

As you can see in the snippet below, I select a record, update it ... and a few lines later the update crashes with a lovely System.Data.Linq.ChangeConflictException saying "Row not found or changed". How is that possible? I'm sure that nobody modifies or deletes the data in the meantime.

private void updatePerson(Person person)
{
	var localPerson = DataStore.Data.Persons.Where(p => p.Id == person.Id);
	if(localPerson == null)
	{
		//person is new, so create it
		DataStore.Data.Persons.InsertOnSubmit(person);
	}
	else
	{
		//update existing person
		localPerson.Name = person.Name;
		localPerson.CustomerId = person.CustomerId;
		localPerson.DepartmentId = person.DepartmentId;
		localPerson.IsActive = person.IsActive;
	}
	
	DataStore.Data.SubmitChanges(); //crash boom bang --> Row not found or changed.
}

Aha! LINQ to SQL uses Optimistic Concurrency

Hahaaa, that's it! When LINQ to SQL selects a record, it does not lock any data. When it is updating a record, it compares all columns with their original values.

So what does this mean? The update query that I expected from LINQ to SQL was:

UPDATE Persons
SET Name = 'Mr. Buggy',
	CustomerId = null,
	DepartmentId = 6,
	IsActive = true
WHERE
	Id = 9999

But the real world is different; due to optimistic concurrency it compared all columns:

UPDATE Persons
SET Name = 'Mr. Buggy',
	CustomerId = null,
	DepartmentId = 6,
	IsActive = true
WHERE
	Id = 9999 AND
	Name = 'Mr. Buggy' AND
	CustomerId = 1234 AND
	DepartmentId = 1 AND
	IsActive = true

This still does neither explain nor solve my issue, since my original values did not change in the meantime. But with the knowledge of Optimistic Concurrency and a few more minutes of debugging, I found (my) fault: The database field for CustomerId is not nullable ... but the REST Service returned null.

I fixed this and everyone (that's me) is happy!

Default Mobile Viewport Width

Recently I've done some optimizations for mobile websites where I focused on the default viewport size of common mobile browsers.

Here's the list of the default viewport width I used:

Windows Phone 7 IE: 1024px
Android: 800px
iPhone Safari: 980px
Opera Mobile: 850px