Windows Phone recipes are open source (MSPL) projects aimed at helping Windows Phone developers with their Windows Phone applications. Recipes are usually common patterns for topics that require some attention. The idea is to provide a sample with some reusable code that can be reused later and modified to fit other similar scenarios. Developers are more than welcome to use them as is, or to change them as they see fit.
At this blog I am trying to keep up with best practices and latest .NET technologies.
Dienstag, 14. Dezember 2010
Samstag, 11. Dezember 2010
Windows Phone 7: Grid style listbox
If you want to implement a grid for your Windows Phone 7 app you have to use a Listbox control because of the missing DataGrid at the Windows Phone 7 platform. A first idea for contsructing a Grid then could be to use the WrapPanel control in your ItemTemplate of the Listbox control. But if you do this, the data virtualization of the ListBox will be disabled (Virtualizing Data in Windows Phone 7 Silverlight Applications - Peter Torr's Blog - Site Home - MSDN Blogs). This will increase the loading time of your ListBox and results in a very poor UX handling. The problem is, that you can not use any complex data structures in the ItemTemplate at a Listbox for Windows Phone 7. Every line in the Listbox should be one data line. So a solution for developing a grid styled Listbox is to implement a RowAdapter class for your bounded data.
Here a implementation of a RowAdapter, I used in one of my projects:
public class RowAdapter<TItemType> : IList<IEnumerable<TItemType>>, INotifyCollectionChanged
{
private readonly IList<TItemType> _sourceList;
private readonly int _columns;
private class RowObject : IEnumerable<TItemType>
{
internal readonly RowAdapter<TItemType> Parent;
internal readonly int StartIndex;
public RowObject(RowAdapter<TItemType> parent, int startIndex)
{
Parent = parent;
StartIndex = startIndex;
}
#region IEnumerable<TItemType> Members
public IEnumerator<TItemType> GetEnumerator()
{
int limit = Parent._sourceList.Count;
int end = Math.Min(StartIndex + Parent._columns, limit);
for (int pos = StartIndex; pos < end; ++pos)
{
yield return Parent._sourceList[pos];
}
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
public RowAdapter(IList<TItemType> sourceList, int columns)
{
if (null == sourceList)
throw new ArgumentNullException("sourceList", Resource.RowAdapter_RowAdapter_sourceList_is_null);
if (columns <= 0)
throw new ArgumentOutOfRangeException("columns", Resource.RowAdapter_RowAdapter_ColumnsGreaterOne);
// We require the source list to implement IList because we
// need to know how many item there are
_sourceList = sourceList;
_columns = columns;
var sourceNotify = sourceList as INotifyCollectionChanged;
if (null != sourceNotify)
{
sourceNotify.CollectionChanged += OnSourceCollectionChanged;
}
}
#region IList<IEnumerable<TItemType>> Members
public int IndexOf(IEnumerable<TItemType> item)
{
var realItem = item as RowObject;
if (null == realItem || !ReferenceEquals(realItem.Parent, this))
return -1; // It does not belong to this collection
Debug.Assert(0 == realItem.StartIndex % _columns, "RowObject item has a wierd index");
return realItem.StartIndex / _columns;
}
public void Insert(int index, IEnumerable<TItemType> item)
{
throw new NotSupportedException();
}
public IEnumerable<TItemType> this[int index]
{
get
{
if (index < 0 || index > Count)
return null;
return InternalGetRow(index);
}
set
{
throw new NotSupportedException();
}
}
public void RemoveAt(int index)
{
throw new NotSupportedException();
}
#endregion
#region ICollection<IEnumerable<TItemType>> Members
public void Add(IEnumerable<TItemType> item)
{
throw new NotSupportedException();
}
public bool Contains(IEnumerable<TItemType> item)
{
var realItem = item as RowObject;
return null != realItem && object.ReferenceEquals(realItem.Parent, this);
}
public void CopyTo(IEnumerable<TItemType>[] array, int arrayIndex)
{
// I haven't implemented this. It is easy to implement if you need it
throw new NotImplementedException();
}
public bool Remove(IEnumerable<TItemType> item)
{
throw new NotSupportedException();
}
public void Clear()
{
throw new NotSupportedException();
}
public int Count
{
get
{
return (_sourceList.Count + (_columns - 1)) / _columns;
}
}
public bool IsReadOnly
{
get { return true; }
}
#endregion
#region IEnumerable<IEnumerable<TItemType>> Members
public IEnumerator<IEnumerable<TItemType>> GetEnumerator()
{
for (int i = 0; i < Count; ++i)
{
yield return InternalGetRow(i);
}
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
private void FireCollectionChanged()
{
var handler = CollectionChanged;
if (null != handler)
{
handler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
private void OnSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
FireCollectionChanged();
}
#endregion
private RowObject InternalGetRow(int index)
{
return new RowObject(this, index * _columns);
}
}
Freitag, 10. Dezember 2010
Windows Phone 7: Some links
- Marketplace Reporting is available and first payements will start: Marketplace: Reporting ist da, erste Zahlungen im Januar - LIFE IN MOTION - Site Home - MSDN Blogs
- Activate more than three developer devices for a Marketplace account: WP7: Mehr als 3 Entwicklergeräte freischalten–wie? - LIFE IN MOTION - Site Home - MSDN Blogs
- How to detect if Zune is running during ChooserTasks: Kodierer [Coder]: Windows Phone Unplugged - How to Detect the Zune Software - Rene Schulte - Coding .Net and Silverlight with C#
- Some nice Windows Phone 7 tutorials: eugenedotnet blog | All about Windows Phone 7 and other Microsoft technologies.
- Windows Phone 7 and Cloud Connection: Windows Phone 7 Developer Guide
Freitag, 3. Dezember 2010
Traps of Windows Azure Development
My personal traps of Windows Azure development for this week are:
- Problems with long project names (longer 248) for the temporary name of my delivery package for running at the Windows Azure emulator
- Use _CSRUN_STATE_DIRECTORY as environment variable to shorten the path
- Remove PlatformTarget from an existing Web project file to avoid compile error
- Strange CommunicationObjectFaultedException error if you use a Source Safe tool and your web.config is read only
- If you use assemblies that are not content of a normal Windows Server 2008 SP2 installation (for example RIA Services), you have to set the properties “Copy Local” to true of the assemblies involved – otherwise you get a never ending “busy” state of your web role at Windows Azure Management Tools
Windows Azure: CommunicationObjectFaultedException
If your web.config is read only you get maybe the following strange error message in a Windows Azure project at runtime. It costs my half a day to find out, that this has nothing to do with my web service configuration or web service usage.
Mittwoch, 1. Dezember 2010
Hosting Silverlight Application with RIA Services as Cloud Service
We have an existing web project (Silverlight 4, WCF RIA Services) that we wanted to bring to the cloud using Windows Azure. We added a new project, Windows Azure Cloud Service and added a new Web Role. After this you can connect your existing web project to this web role. The isolated web project compiles fine, but our new solution brings the following compile error:
“Error 1 The "CreateRiaClientFilesTask" task failed unexpectedly.System.Web.HttpException (0x80004005): Could not load file or assembly 'msshrtmi' or one of its dependencies. An attempt was made to load a program with an incorrect format. ---> System.Configuration.ConfigurationErrorsException: Could not load file or assembly 'msshrtmi' or one of its dependencies. An attempt was made to load a program with an incorrect format. ---> System.BadImageFormatException: Could not load file or assembly 'msshrtmi' or one of its dependencies. An attempt was made to load a program with an incorrect format.”
Strange, what happens and what can we do?
The solution is very easy, but hard to find out: You have to unload your .web project (which hosts the Silverlight application) and edit it the project file. If you now remove the tags
<PlatformTarget>AnyCPU</PlatformTarget>
from the project file, your solution can be compiled !
Sonntag, 28. November 2010
Windows Phone 7: Customize live tiles, push notification
Found a good article of Chris Koenig about customizing the tiles with Windows Phone 7 Push Notification Services:
Customizing WP7 Push Notification Tiles « Development « Chris Koenig
Montag, 22. November 2010
Windows Phone 7: Recording the microphone
Description and sample project for recording something with the Windows Phone 7 microphone.
Windows Phone 7: Video Player with MVVM pattern
If you plan to implement a video player for Windows Phone 7 you could found a good solution using the MVVM pattern here: Windows Phone 7 View Model Style Video Player - CodeProject
Sonntag, 21. November 2010
Windows Phone 7: Create custom Pushpin for Bing maps
Good article about creating a custom Pushpin for Bing maps, that I used for my Runner’s app:
Freitag, 19. November 2010
Windows Phone 7: No forward navigation
Information forward navigation at Windows Phone 7:
Navigation Stack on Windows Phone 7 - Peter Foot - APPA Mundi
“While Windows Phone uses the same NavigationService and page-based model as “regular” Silverlight, one area the documentation doesn’t make clear is that although the APIs seem to support both Back and Forward navigation in reality there is no forward navigation on Windows Phone. This means when you navigate to a new page and then return Back to the previous page you can’t call NavigationService.GoForward() to return. CanGoForward will always return False. In the documentation for System.Windows.Controls.Frame (the base class of PhoneApplicationFrame) GoForward is described as:-
“Navigates to the most recent entry in the forward navigation history, or throws an exception if no entry exists in forward navigation. For Windows Phone this method will always throw an exception because there is no forward navigation stack.”
(my use of bold)”