Application Model and Data Binding on Windows Phone 7

Model-View-ViewModel (MVVM) is a very useful pattern for organizing scalable and constantly evolving phone applications.  In MVVM, Each view is backed by a view-model and a model.  Models are loaded from storage or the network often as pages are displayed to the user. 

Joe Healy co-author of the Teach Yourself Windows Phone 7 Application Development in 24 Hours comments that many phone developers are not using nor are familiar with MVVM and that this pattern is applicable for any app that is sharing global app data across multiple pages.

Sams Teach Yourself Windows Phone 7 Application Development in 24 Hours (Sams Teach Yourself — Hours)

In Phone applications it is desirable for the performance of page navigation to be as fast as possible.  Users do not have the tolerance for waiting several seconds between pages as they do on web applications.  To remedy this, phone applications often place their models at the application scope so that they may be accessed by all the pages.  This does not mean that all the data is loaded at application start though.  The application model acts as a cache for that data that has been loaded.

One implementation might be to define an ApplicationModel class and define it as a resource in the app.xaml file.  Then Any data binding can be trivially done within XAML.  An issue occurs this that approach. 

<Application.Resources>
<app:ApplicationModel x:Key="ApplicationModelK" />
</Application.Resources>
 
<TextBlock Text="{Binding Source={StaticResource ApplicationModelK}, Path=SomeData}"/>
 
 

Both One-Way and Two-Way data binding rely on INotifyPropertyChanged event on the binding.  The Binding also has a reference to the bound UI control which has a reference to the page.  When the user navigates back (exiting the page), the page stack no longer holds a reference to the page and the page would normally get garbage collected. 

 

But since a reference still exists from App->ApplicationModel->SomeData->Binding->UI Control->Page then the page never gets garbage collected.  This page reference leak results in all the resources of the page being held in memory.  Further, when the user returns to the page, a second page instance is created and all the resources reallocated again.  Also, when the ApplicationModel data changes both the old and new instances of the page are notified.

One solution to this is to not bind directly to the global ApplicationModel but instead set the page.DataContext to the ApplicationModel.SomeData when inside of OnNavigatedTo and to set DataContext to null on OnNavigatingFrom.  Then in your binding you bind only to the partial object path rather than the global reference. 

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    DataContext = Application.Current.Resources["ApplicationModelK"];
    base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    DataContext = null;
    base.OnNavigatedFrom(e);
}
 
<TextBlock Text="{Binding SomeData}"/>

 

With this pattern the binding to global data will be removed when exiting the page and the references back to the page will be release allowing the page to be garbage collected.

Posted in Uncategorized | Leave a comment

Performance UI Pattern: Asynchronous Property

Motivation: XAML development thrives on declarative data binding. The means that at author-time a unique path to each piece of data to be displayed is known. At runtime when the data binding is interpreted a property is called to retrieve the data. This retrieval may take time causing a delay for each visual element in a displayed user interface.

Anti-pattern 1: Data is loaded then it is presented to the UI. In this anti-pattern the developer often loads more content than needed for the currently visible user interface. This causes more delay before the UI is fully presented.

Anti-pattern 2: On-demand loading of properties (Lazy Initialization Pattern) as they are presented in UI. In this anti-pattern the data the retrieved when it is first requested. This property get blocks until the property data is ready.

Asynchronous Property Pattern: This pattern allows for on-demand request of the property which instantly returns an object which represents the property which will be populated once the load is completed. The asynchronous property provides properties for value and status. Because the asynchronous property is retrieved installs, data binding to both the value and the status.

AsyncProperty demonstration Windows Phone 7 application download here:

http://cid-ac1291870308f748.skydrive.live.com/embedicon.aspx/Public/AsyncPropertyDemo.zip

Posted in Uncategorized | Leave a comment

Updating ApplicationBarIconButton dynamically

Since the ApplicationBar is not a DependencyObject and not part of the visual tree, FindElement cannot locate Items in the ApplicationBar with x:Name set.  The members will be null.

 

Due to this, it may be best to initialize the ApplicationBar using code behind and hold references to items which need to be dynamically changed.

 

Notice in the code below that SaveEdit reference is held and SaveEdit.IsEnabled is updated with each keypress into the TextBox.

 

#region AppBar

private ApplicationBarIconButton SaveEdit;

private void InitAppBar()

{

ApplicationBar appBar = new ApplicationBar();

appBar = new ApplicationBar();

 

SaveEdit = new ApplicationBarIconButton(new Uri(“images/appbar.check.rest.png”, UriKind.Relative));

SaveEdit.Click += new EventHandler(OnClick_Check);

//SaveEdit.Text = Strings.Save_button;

appBar.Buttons.Add(SaveEdit);

 

ApplicationBarIconButton CancelEdit = new ApplicationBarIconButton(new Uri(“images/appbar.close.rest.png”, UriKind.Relative));

CancelEdit.Click += new EventHandler(OnClick_Cancel);

//CancelEdit.Text = Strings.Cancel_button;

appBar.Buttons.Add(CancelEdit);

 

ApplicationBar = appBar;

}

#endregion AppBar

       

 

 

void itemName_KeyDown(object sender, KeyEventArgs e)

{

bool isNameValid = itemName.Text.Length != 0;

           

if ((e.Key == Key.Enter) && isNameValid)

{

SaveAndExit();

}

           

SaveEdit.IsEnabled = isNameValid;

}

 

Posted in development, wp7 | Leave a comment

Ship it! One Giant Rubik’s Cube

 

In February I was on a ski trip with some friends and Barry began talking about building a giant Rubik’s Cube.  This week, just 6 months later the Groovik’s Cube was assembled at Burningman and looks spectacular.  It was event mentioned in Gizmodo.

The project involved 9 project leads, over 50 volunteers, and many hours of volunteer work.  Bringing together skills from electronics, software, fabric, adhesives, and metal. 

Early in the project, Rhonda created a simulator for the project so we could see how our control scheme would work.  This early feedback allowed us to discuss and change our user interface scheme.

I was a lead on the electronics side focusing on production of surface mount circuits to regulate current to the hundreds of super bright LEDs.  I did not attend Burningman to witness the cube in person ad our timeline did not allow us to do a fully assembly before.  So, I have yet to see the whole cube operating.  I bet it is quite a site!

Posted in Uncategorized | Leave a comment

Live Geometry

Here is a great example of the richness that can be created with simple tools available with Silverlight.

 Live Geometry

Posted in Uncategorized | Leave a comment

Serializer .NET Robot Controller

 

This looks like a decent board with support to multiple wireless computer interfaces.

Serializer .NET Robot Controller

Posted in Hobbies | Leave a comment

New Cider Adorner Placement API’s

In my last post I discussed the 3 adorner spaces in the new Cider adorner placement API’s.  In this post I will discuss these API’s  in a little more detail.  Note at the time of this writing, the spcific class and property names have not been finalized.  jnak will be asking for your input in his blog See Win App.  We’d like to know your thoughts on the names since we traditionally work with a single coordinate system in user interface developement, supporting 3 coordinate systems can be confusing. 

The driving goal of the last set of changes has been to support a concept of layout space.  I’ve also taken this opportunity to simplify the setting of adorner placement and open the adorner panel arrange so it can be extended by external developers.  I’ve tried to simplify this so developer can create designer features without dealing with the math am atricies associated with layout transforms, render transforms, right-to-left(RTL) language transforms, and zomming content in the designer view.  With you help we can take this next step at nameing and organizing these classes and properties to make them easiest to use.

Please visit jnak’s blog and give us your feedack See Win App.

In this example, the parent grid has a render transform X-skew of 5 degrees. Though this scenario is useful for demonstrating the affects of the different spaces.

Notice the selection frame and grab handles in the grid are unaffected by the skew of the grid render transform. These adorners are adorning the position the grid is within its parent. Since the grid’s parent is unaffected by the grid’s render transform, the grid layout space is also unaffected by this transform.

Notice that the button’s selection frame and grab handles ARE affected by the render transform of the grid. Since the layout position of the button is in the coordinate system of the rendered grid, the square layout slot of the button has been skewed by the transform.

 

Scenario: Top Grid Rail

Here is the code for placement of the top grid rail. This adorner is in the render space of the grid, is stretched from the left hand to the right hand side of the grid, is positioned outside the top grid edge, and has a height determined by the adorner XAML style. The height does not scale when the designer zooms in.

// start with empty placement
ContributionGroup placement = new ContributionGroup();
placement.Add(new SizeRelativeToAdornerDesiredHeight(this, 1.0, 0));
placement.Add(new SizeRelativeToContentRenderWidth(null, 1.0, 0));
placement.Add(new PositionRelativeToAdornerHeight(this, 0, -offsetY));
AdornerPanel.SetPlacement(this, placement);
AdornerPanel.SetHorizontalStretch(this, AdornerStretch.Stretch);
AdornerPanel.SetVerticalStretch(this, AdornerStretch.None);

Scenario: TopRightGrabHandle

This adorner is sized to the according to the XAML style. This adorner is positioned in the layout space of the adorned element and positions at the right hand side of the adorned element. The position is adjusted 3 pixels further right and upward by the height of the adorner plus 3 pixels in order to locate it outside of the top right edge fo the adorned element’s layout position.

ContributionGroup placement = new ContributionGroup();
placement.Add(new SizeRelativeToAdornerDesiredWidth(this, 1.0, 0));
placement.Add(new SizeRelativeToAdornerDesiredHeight(this, 1.0, 0));
placement.Add(new PositionAtContentLayoutSlot(null));
placement.Add(new PositionRelativeToContentLayoutWidth(null, 1.0, 0));
placement.Add(new PositionRelativeToAdornerWidth(this, 0, -3.0));
placement.Add(new PositionRelativeToAdornerHeight(this, -1.0, 3.0));
AdornerPanel.SetPlacement(this, placement);

Proposed Placement Classes

Contribution Group

This is a collection of class instances that declare adjustments to the adorner size and position.  This is a temporary name, other names we have tossed around are ArrangementGroup and PlacementGroup.

Please offer you suggestion at jnak’s blog.

Adorner Space

The adorner space properties allow you to adjust the size off the adorner based on the desired size determined by the style size of the adorner.  Adorner position can be adjusted relative to the final computed size fo the adorner.  Size and position can also be adjusted in pixels.  Adorner space does nto scale when the designer zooms in/out.

SizeRelativeToAdornerDesiredHeight(relativeTo, factor, offset)
SizeRelativeToAdornerDesiredWidth(relativeTo, factor, offset)
PositionRelativeToAdornerHeight(relativeTo, factor, offset)
PositionRelativeToAdornerWidth(relativeTo, factor, offset)

Render Space

The render space properties allow you to adjust the size or position of the adorner relative to the adorned element and by an offset measured in pixels in thatcoordinate system.  Render space size and positions adjustments are affected by and transform that affects the render size and shape of the adorned element.

SizeRelativeToContentRenderHeight(relativeTo, factor, offset)
SizeRelativeToContentRenderWidth(relativeTo, factor, offset)
PositionRelativeToContentRenderHeight(relativeTo, factor, offset)
PositionRelativeToContentRenderWidth(relativeTo, factor, offset)

LayoutSpace

The layout space properties allow you to adjust the size or position of the adorner relative to the layout slot fo the adorned element and an offset measured in pixels of that coordinate system.  Layout space size and positions are afected by transforms that affect the render space of the adorned element parent.

SizeRelativeToContentLayoutHeight(relativeTo, factor, offset)
SizeRelativeToContentLayoutWidth(relativeTo, factor, offset)
PositionAtContentLayoutSlot(relativeTo )
PositionRelativeToContentLayoutHeight(relativeTo, factor, offset)
PositionRelativeToContentLayoutWidth(relativeTo, factor, offset)

Posted in Uncategorized | Leave a comment

Layout Space Adornment in Cider

I have recently been redesigning the architecture used to specify adorner placement within Cider.  This is a good time for us to get to a common understanding of the coordinate systems that affect our adorners in WPF and how they can affect the designer surface.

First, I suggest thinking of render space as a child of layout space. Then the layout moves, the render space moves accordingly.

Next note that render space can move in relation to layout space. This movement can be in any direction and can even place the rendered control outside of the layout space entirely. Render space can also be used to scale and element to be larger or smaller than the layout size of the element.

Consider the following example, the button has been scaled down in size using a RenderTransform with scale dimensions less than 1.0.

Layout properties in WPF such as Margin, Grid.Row, Grid.Column, Width, Height affect the layout space of the element and are relative to the render space of the parent element. So when we talk about the layout space of an element this maps to the render space of the element’s parent.

Any adorners which interact with these layout properties must also be placed in the layout space. Grab handles or resize adorners for instance are in layout space since they are directly displaying and affecting the layout. In the example given, the grab handles appear some distance away from the edge of the button because they are not affected by the render transform causing the button to be smaller than the space given to it by the layout properties.

The adorner space is used to define dimensions of the adorner that do not change in size when the designer surface is zoomed.  (Yes, Cider generally supports zooming.  The Cider team has not yet had the time to design the UI and verification tests in order to insure zooming is a high quality experience.)

Most commonly adorner developers are adorning content displayed witin the render space of a control.  Layout space adornments will be needed if you are implmenting a layout tool or custom panel adorners. 

This new design allows adorners to be easily created in the layout space as well as the render space, or the designer view space as before.  Feature designers should consider which space they expect to adorn.  If in doubt, I’d suggest applying a render transform as I did above.  And design your adorners with this distinct difference between the layout space and render space. 

In a later post I will discuss the properties used to position adorners. 

Posted in Uncategorized | Leave a comment

XNA GSE – Free Game Development Tools

If you have a machine still running Windows XP SP2 and you’d like to play with some fun simple game development code, check out XNA Game Studio Express. 

http://msdn.microsoft.com/directx/xna/gse/

This install requires Visual C# Express to first be installed.  Visual C# Express can co-exist with the full versions of Visual Studio and does not share any settings, so will not interfere in any way. Visual C# Express Download Page

What is GSE?

GSE is a game development environment for Visual Studio.  GSE is provided to the community to stimulate a healthy hobbyist and student game development ecosystem.  By having a common (and free) platform people can develop, learn and share games and code libraries.

Where can GSE created games run?

Currently on Windows computers.  Next they will be able to run on Xbox 360 systems.  Beyond that, the imagination is the limit.  Keeping in mind that basic graphics services and 3D rendering are needed.

What’s the best way to get started?

Install Visual C# Express.  Then install GSE.  Open Visual C# Express and Create New Project.  Choose "Space Wars Project"

Space Wars

Space Wars is a sample project that implements a simple game.  This game watches user input, loads and renders graphics, plays sounds, ad simulates some simple physics.  There is plenty here to explore.

Read more about the history of Spacewar!

In my next post I will give a bit of a tour of the Space Wars sample.

Posted in Uncategorized | 23 Comments

WPF Rendering – #1

WPF offers distinctly different techniques for rendering graphical elements. The top level is adding shape elements such as Rectangle, Ellipse, and Path to a Panel element. This is what we see in the multitude of XAML based samples. Below I explore another technique involving implementing OnRender on a class derived from UIElement.

Rendering within UIElement::OnRender()

Implementing within UIElement is accomplished by implementing OnRender. OnRender is provide with DrawingContext. This context offers methods for drawing text and geometry.

class UIElmentOnRenderDemo : UIElement {
    protected override void OnRender(DrawingContext drawingContext)   { … }
}

When the parent of the UIElement detects that the size has changed, OnRender is called. Within OnRender we can generate render geometries and make calls to the drawing context to render them.

Rect rect = new Rect(new Point(5, 10), new Size(100, 20)));

Geometry outline = new RectangleGeometry(rect);

drawingContext.DrawGeometry( brush, pen, outline);

Note that the rectangle was intended to be rendered with a single pixel line and is showed at thicker with sfoter edges. The is result of "anti-aliasing" in order to soften the images on eh screen. Here is a close-up.

RenderOptions.SetEdgeMode can be used to turn off antialiasing for all non-text render output within the UIElement. Setting Edge mode for individual geometry has no effect. EdgeMode has no effect on text rendering.

RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);

With EdeMode set on UIElement the rectangle is rendered crisply. 

Note: I’ll be invesigating rendering in more depth in upcoming blog entries.  Problems arise when rendering on 120 DPI displays.  I’ll also delve into more complex geometries and the use of guidelines.

Posted in Uncategorized | 4 Comments