Session 9 of the WinRT Development Class – Intro to Model-View-ViewModel (MVVM)

WinRTWebBanner_JPEG

This class was really made possible by all those who attended. And a special thanks to Tom Hannum for lending me your power cord. We all learned a lot at this session. I hope everyone will go review the presentation video and get familiar with MVVM. If you have any questions leave a comment below! Happy Coding!

Session Resources

Overview of Sessions

The links below lead you to Meetup Events where you can RSVP. We look forward to seeing you at our next session!

1. Introductory Lecture (Nov 27th by Danny & Kevin)
2. Introduction to XAML and WinRT’s powerful Control Framework; (Dec 4th by Danny & Kevin Click here for the video recording)
3. Page-Navigation Model and Application Lifecycle (Jan 8th by Danny Click here for the video recording)
4. Fundamentals (Async/Await, WinRT API, Security) (Jan 15th by Kevin Click here for the video recording)
5. Settings and Search Contract (Jan 28th by Danny Click here for the video recording)
6. Share Contract (Feb 4th by Kevin Click here for the video recording)
7. Live Tiles and Background Tasks (March 18th by Kevin Click here for the video recording)
8. Orientation Handling and Proximity using Near Field Communication (NFC) (March 25th by Danny Click here for the video recording)
9. Introduction to ModelViewViewModel (MVVM) (April 8th by Danny Click here for the video recording)
10. InterKnowlogy’s WinRT MVVM Framework Session Part I/II(April 22nd by Kevin)
11. InterKnowlogy’s WinRT MVVM Framework Session Part II/II(May 6th by Danny)
12. Presentation of Hackathon Results + Certificate/Prize Giveaway(May 20th by Danny and Kevin)

Session 5 of the WinRT Development Class – Search and Settings

WinRTWebBanner_JPEG

 

What a crazy session! We pulled through it like champs! Thank you everyone who attended. It was a blast and we are working with our sponsors to ensure future sessions go much smoother.

Session Resources

Next session will mark the half way point so don’t miss it! Kevin will be presenting about the Share Contract on Monday February 4th! It’s going to be great!

Overview of Sessions

The links below lead you to Meetup Events where you can RSVP. We look forward to seeing you at our next session!

1. Introductory Lecture (Nov 27th by Danny & Kevin)
2. Introduction to XAML and WinRT’s powerful Control Framework; (Dec 4th by Danny & Kevin Click here for the video recording)
3. Page-Navigation Model and Application Lifecycle (Jan 8th by Danny Click here for the video recording)
4. Fundamentals (Async/Await, WinRT API, Security) (Jan 15th by Kevin Click here for the video recording)
5. Settings and Search Contract (Jan 28th by Danny Click here for the video recording)
6. Share Contract (Feb 4th by Kevin)
7. Live Tiles and Background Tasks (March 18th by Kevin)
8. Orientation Handling and Proximity using Near Field Communication (NFC) (March 25th by Danny)
9. Introduction to ModelViewViewModel (MVVM) (April 8th by Danny)
10. InterKnowlogy’s WinRT MVVM Framework Session Part I/II(April 22nd by Kevin)
11. InterKnowlogy’s WinRT MVVM Framework Session Part II/II(May 6th by Danny)
12. Presentation of Hackathon Results + Certificate/Prize Giveaway(May 22nd by Danny and Kevin)

Session 4 of the WinRT Development Class – Async/Await, WinRT API, and Security

Thank you all for attending Session 4 of our WinRT Development Course. It was great to see you all understand, embrace and use the new WinRT API! J

Session Resources:

  • AsyncDemonstration.zip: Source code of the project I used to demonstrate the difference between synchronous and asynchronous code execution
  • DemoFinal.zip: Source code of the project we developed together. This application allows to take a picture from an attached webcam, save it in the Pictures Library and create diary entries.
  • Presentation.pptx: The slide deck
  • Session Recording
  • HomeworkFinal.zip: Sample implementation of the homework (please try to solve it on your own first!)

Please don’t forget about Danny’s upcoming session on Monday – Jan 28th! I will see you all again on February 4th!

Overview of sessions

The links below lead you to Meetup Events where you can RSVP. We look forward to seeing you at our next session!

1. Introductory Lecture (Nov 27th by Danny & Kevin)
2. Introduction to XAML and WinRT’s powerful Control Framework; (Dec 4th by Danny & Kevin Click here for the video recording)
3. Page-Navigation Model and Application Lifecycle (Jan 8th by Danny Click here for the video recording)
4. Fundamentals (Async/Await, WinRT API, Security) (Jan 15th by Kevin Click here for the video recording)
5. Settings and Search Contract (Jan 28th by Danny)
6. Share Contract (Feb 4th by Kevin)
7. Live Tiles and Background Tasks (March 18th by Kevin)
8. Orientation Handling and Proximity using Near Field Communication (NFC) (March 25th by Danny)
9. Introduction to ModelViewViewModel (MVVM) (April 8th by Danny)
10. InterKnowlogy’s WinRT MVVM Framework Session Part I/II(April 22nd by Kevin)
11. InterKnowlogy’s WinRT MVVM Framework Session Part II/II(May 6th by Danny)
12. Presentation of Hackathon Results + Certificate/Prize Giveaway(May 22nd by Danny and Kevin)

Impressions





Session 3 of the WinRT Development Class – App Lifecycle and Navigation

WinRTWebBannerSmall_JPEG

What an excellent session! I know it’s been a little over a week, but I’m very grateful to all those who attended! For those of you who were not able to attend we have a video of the session! Please find the class resources and link to the video below.

Session 3 Resources

Overview of Sessions

The links below lead you to Meetup Events where you can RSVP. We look forward to seeing you at our next session!

1. Introductory Lecture (Nov 27th by Danny & Kevin)
2. Introduction to XAML and WinRT’s powerful Control Framework; (Dec 4th by Danny & Kevin Click here for the video recording)
3. Page-Navigation Model and Application Lifecycle (Jan 8th by Danny Click here for the video recording)
4. Fundamentals (Async/Await, WinRT API, Security) (Jan 15th by Kevin Click here for the video recording)
5. Settings and Search Contract (Jan 28th by Danny)
6. Share Contract (Feb 4th by Kevin)
7. Live Tiles and Background Tasks (March 18th by Kevin)
8. Orientation Handling and Proximity using Near Field Communication (NFC) (March 25th by Danny)
9. Introduction to ModelViewViewModel (MVVM) (April 8th by Danny)
10. InterKnowlogy’s WinRT MVVM Framework Session Part I/II(April 22nd by Kevin)
11. InterKnowlogy’s WinRT MVVM Framework Session Part II/II(May 6th by Danny)
12. Presentation of Hackathon Results + Certificate/Prize Giveaway(May 22nd by Danny and Kevin)

Session 1 & 2 of the WinRT Development Class – Introduction, XAML, and WinRT’s Control Framework

WinRTWebBannerSmall_JPEG

 

The first two sessions of the WinRT Development class were a great introduction to what Windows 8 WinRT development really is and to XAML development. We’re very excited about the future sessions and hope every developer will come learn with us about developing WinRT apps!

Session 1 Resources

Session 2 Resources

 

Overview of Sessions

The links below lead you to Meetup Events where you can RSVP. We look forward to seeing you at our next session!

1. Introductory Lecture (Nov 27th by Danny & Kevin)
2. Introduction to XAML and WinRT’s powerful Control Framework; (Dec 4th by Danny & Kevin Click here for the video recording)
3. Page-Navigation Model and Application Lifecycle (Jan 8th by Danny)
4. Fundamentals (Async/Await, WinRT API, Security) (Jan 15th by Kevin)
5. Settings and Search Contract (Jan 28th by Danny)
6. Share Contract (Feb 4th by Kevin)
7. Live Tiles and Background Tasks (March 18th by Kevin)
8. Orientation Handling and Proximity using Near Field Communication (NFC) (March 25th by Danny)
9. Introduction to ModelViewViewModel (MVVM) (April 8th by Danny)
10. InterKnowlogy’s WinRT MVVM Framework Session Part I/II(April 22nd by Kevin)
11. InterKnowlogy’s WinRT MVVM Framework Session Part II/II(May 6th by Danny)
12. Presentation of Hackathon Results + Certificate/Prize Giveaway(May 22nd by Danny and Kevin)

WinRT and “Fun” (ok, PAIN) With a Grouped GridView

I’ve seen examples of the new WinRT GridView in a bunch of the samples and demos from Microsoft, but had never used the control for my own app before.  During the past couple weeks of RECESS, I’ve been writing a Ping Pong results tracking app with a couple co-workers, and set out to use the GridView in grouped mode.  (Yes, PING PONG – we got a new table at the office a few months ago, and the competition is getting intense. We need to start recording these results!)

As with almost all demos from Microsoft, the app uses some not-so-real-world techniques: manipulating UI from code-behind, and creating the data source from in-memory data stores.  I’m using an MVVM design and getting real data from a real (MongoDB backed) web service.  This is just a quick post on what did and did not work for me when learning the GridView via trial and error.

For all the code below, I’m using a simple hierarchical data structure:  Teams that contain a collection Players.

Bind GridView Directly to a VM Collection – Does Not Work

    Teams = DataModel.GetTeams();
    <GridView ItemsSource="{Binding Path=Teams}"
              Margin="5"
              >

This works (well, it displays the outermost collection of objects, but doesn’t do any grouping).  For the GridView to use grouped data, you must provide a CollectionViewSource with IsSourceGrouped set to true.  I can’t find anywhere that you can tell the GridView directly that it’s ItemsSource contains grouped data.

Create CollectionViewSource Manually – Does Not Work

I’ve seen the CollectionViewSource created as a resource in the UI View in all the samples, but since I’m using MVVM, I want to bind to VM properties. I try to create and store a CollectionViewSource in the VM and bind straight to it.

    Teams = DataModel.GetTeams();
	
    CVS = new CollectionViewSource
    {
        Source = Teams,
        IsSourceGrouped = true,
    };
    <GridView ItemsSource="{Binding Path=CVS}"
              Margin="50"
            >

I get an ArgumentException in the CollectionViewSource property setter (via the NotifyPropertyChanged event).  This occurs when the GridView that is bound to that CVS doesn’t like what it sees.

Bind Resource to VM Property – Works

Here’s a compromise, I never realized you could do this.  Declare the CollectionViewSource in XAML (set IsSourceGrouped), but bind it’s source to the VM property. Notice I’m also able to set ItemsPath to describe what property in the parent type holds the children.

    <Page.Resources>
        <CollectionViewSource x:Key="GroupedData" 
                              IsSourceGrouped="True"
                              Source="{Binding Teams}"
                              ItemsPath="Players"
                              />
    </Page.Resources>
	
    <GridView ItemsSource="{Binding Source={StaticResource GroupedData}}"
                Margin="50"
                SelectionMode="Single"
                >
    Teams = DataModel.GetTeams();

Use a LINQ Group By Directly – Works

All the samples I’ve seen use a LINQ query to fetch grouped results, and then push those results into a custom data structure.  I originally thought you had to do this for the GridView to understand the grouping, but it’s not required. I see a bunch of discussions where the collection must implement a certain interface, or where you must write your own wrapper classes that derive from IGrouping, etc. but those don’t seem to be required either.

Here I’m setting my grouped LINQ query as the property that the GridView will bind to (again via the CollectionViewSource resource).  Notice a couple things:

  • I’m unnecessarily using LINQ to group my results even though my data is already in a hierarchy (this is just to prove a point)
  • You can project the LINQ results into either concrete types or anonymous types. The GridView, as with any other WinRT UI element, is happy to bind to anonymous types (I remember this was a problem in early versions of WinRT, but seems to be fixed now)
  • The LINQ group container is a string/collection dictionary (Team.Name to Teams in my case), so I cheat a little and call .First() to get to the one and only Team in each group, since I know I have unique team names.
    Teams = DataModel.GetTeams();
    GroupedLinq = from team in Teams
                    group team by team.Name
                        into g
                        //select new Team
                        //{
                        //	Name = g.Key,
                        //	Players = new List<Player>( g.First().Players )
                        //};
                        select new
                        {
                            Name = g.Key,
                            Players = g.First().Players
                        };
    <CollectionViewSource x:Key="GroupedLinqData" 
                            IsSourceGrouped="True"
                            Source="{Binding GroupedLinq}"
                            ItemsPath="Players"
                            />

    <GridView ItemsSource="{Binding Source={StaticResource GroupedLinqData}}"
                Margin="50"
                SelectionMode="Single"
                >
        <GridView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Path=Name}"
                            Width="200"
                            Margin="5"
                            />
            </DataTemplate>
        </GridView.ItemTemplate>

        <GridView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Name}"
                                    FontSize="36"
                                    />
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>

                <GroupStyle.Panel>
                    <ItemsPanelTemplate>
                        <VariableSizedWrapGrid Orientation="Vertical" Height="200" />
                    </ItemsPanelTemplate>
                </GroupStyle.Panel>
            </GroupStyle>
        </GridView.GroupStyle>

    </GridView>

Summary

I hope these examples help you get through the learning curve of the GridView faster than I did.

 
 

Accessing Dependency Property (DP) Changed in WinRT

With the release of Windows 8 and WinRT, I began the process, during RECESS, of porting an existing app we’d created for the Microsoft Surface (the team that is now called “Pixel Sense”) to be a Windows Store application. The application followed more of an MVC (Model View Controller) approach, rather than MVVM (Model View ViewModel), so there we a number of controls that subscribed to the DataContext and Visibility changed events in their code behind, which don’t exist in WinRT.

WinRT (Windows Store) applications seem to have many of the same limitations that Silverlight had, compared to WPF, and rather than rewrite the parts of the application to try and avoid needing to know when these DPs changed, I came up with a simple framework to register for a callback when a specified DP changed.

First Solution

The way to get around this issue was actually really straight forward. In each control, I created and registered a DP for each DP I wanted a change notification from (ie. DataContextEx, VisibilityEx, etc…).

public static readonly DependencyProperty DataContextExProperty =
		  DependencyProperty.Register( "DataContextEx", typeof( object ), typeof(DemoControl ),
			new PropertyMetadata( null, OnDataContextExChanged ) );

public object DataContextEx
{
	get { return (object)GetValue( DataContextExProperty ); }
	set { SetValue( DataContextExProperty, value ); }
}

private static void OnDataContextExChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
{
	( (DemoControl)d ).OnDataContextExChanged( e );
}

private void OnDataContextExChanged( DependencyPropertyChangedEventArgs e )
{
	//Handle the change
}

Then, in the control’s constructor, I bound the created DP(s) to the related DP I wanted to know had changed. With this binding, whenever the source DP (ie. DataContext, Visibility, etc…) changed it would cause the “extension” DP to change and that would call the changed handler I registered when creating the DP.

var binding = new Binding
			{
				Path = new PropertyPath("DataContext"),
				RelativeSource = new RelativeSource
								{
									 Mode = RelativeSourceMode.Self
								}
			};
SetBinding(DataContextExProperty, binding);

With this I had all that I needed. However, I hated the idea of having to rewrite this code on every control that I needed the notification on. So I decided to create a framework to allow me to register for a changed callback on any FrameworkElement.

Framework

I decided to go the route of creating a FrameworkElement extension method called RegisterDependencyPropertyChanged that takes a lambda expression for the property to bind to and a callback for when that property changes.

this.RegisterDependencyPropertyChanged( () => DataContext, DataContextChangedHandler );

The extension then calls RegisterDependencyPropertyBinding on FrameworkElementAttachedProperties. FrameworkElementAttachedProperties is an internal class that holds the functionality to create and register an Attached DP for each type of DP (ie. DataContext, IsHitTestVisible, Visibility, etc..) the user desires a callback for and bind that Attached DP to the DP (using the same process defined under First Solution. Then whenever that value changes it attempts to find a callback registered for it, and if one is found, calls the registered callback with the DependencyPropertyChangedEventArgs provided.

Attached DPs are only able to be bound to one property of an object at a time (but can be bound to the same property of multiple objects). This is why an Attached DP is created and registered for each DP of a control as there may be a case where a change callback is registered for more than one property of that control. Therefore whenever FrameworkElementAttachedProperties.RegisterDependencyPropertyBinding is called it calls GetNextUnusedAttachedPropertyForFrameworkElement. This either grabs an existing Attached DP registered for that property, or it will create and register a new one and return it.

private static DependencyProperty GetNextUnusedAttachedPropertyForFrameworkElement( string propertyName )
{
	if ( !_staticExtensionDPs.ContainsKey( propertyName ) )
	{
		var unusedDependencyProperty = DependencyProperty.RegisterAttached( _extensionDPsNamePrefix + "_" + propertyName,
													   typeof( object ),
													   typeof( FrameworkElementAttachedProperties ),
													   new PropertyMetadata( null, DependencyPropertyExPropertyChanged ) );
		_staticExtensionDPs.Add( propertyName, unusedDependencyProperty );
	}
	
	return _staticExtensionDPs[propertyName];
}

The registered callbacks are stored in the DependencyPropertyCallbacks Attached DP on FrameworkElementAttachedProperties. By storing the callbacks in the Attached DP, when the control that has registered is unloaded, it can be collected by the Garbage Collector and there aren’t memory leaks.

Conclusion

I tend to prefer the MVVM approach, but there are cases when constraints dictate that a different approach is used. This is a nice little addition for when that occurs. Here is a demo solution containing the framework (FrameworkElementExtension.cs) and an example of how to use it.

Informant Architecture

With the release of Informant v0.1.5.0 today I wanted to take a minute and talk about some of the changes and challenges I faced with this iteration. Let me first tell you what my goal was with this iteration. I wanted to create a single code base that could be reused in the Windows Service world as well as in WPF4, Silverlight 4, and Windows Phone 7. The challenge was finding which kind of class library can be shared with other kinds of applications. I discovered that Silverlight 3 was the appropriate base library type to use. Any .NET solution can reference SL3 libraries. I hoped to be able to make all of my model objects in SL3 assemblies and share them across all applications. However, I ran into some show stoppers in namespace conflicts. The model objects would be used in WCF therefore they needed to have DataContract and DataMemeber attributes applied to them. The namespace System.Runtime.Serialization cannot be shared between SL3 and WPF4. I got the following exception when I tried this: “Could not load file or assembly ‘System.Runtime.Serialization, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e’ or one of its dependencies. The system cannot find the file specified.” WPF4 does not understand and is not compatible with this version of the SL3 framework. Super big bummer! This meant that I could only use Interfaces to enforce my model object APIs. Since I wanted consistency this is exactly what I did. Only one SL3 library is shared between all of the UI applications and the Windows Service.

The next hurdle was handling a WCF service reference that would work in all scenarios. I found that this was also not possible, or rather was not ideal for my situation. I wanted my WPF4 application to be very rich and have have duplex channels which are not supported in SL3/4 or Wp7. This meant that every framework had to have it’s own non-reusable reference to the service. These references live in the DataProviders.[Framework] assemblies. Even though I know that the model objects coming from the service are implementing the Interfaces defined in the shared library, I cannot treat these objects as those Interfaces when they come out of the service. I must be able to do this in order for my UI, ViewModels, and other DataProvider dependent assemblies to be shared across frameworks. To overcome this I made a partial class for each model object coming from the service and had the partial I made implement the correct Interface. This caused two problems for me. First, the Interfaces were using IEnumerable<T> which is not supported in WCF. The models from WCF all use List<T> when they come across the wire. In order to solve this I had to tell WCF to change the names of the IEnumerable<T> properties when they were sent across the wire and I had to make each IEnumerable<T> property in the partial I made use the List<T> property from the WCF partial class as the backing field. This was preferred over changing the Interfaces to enforce desired behavior. Second, there was an error that said the WCF partial and the partial I made had difference base classes after I implemented the Interface. This was so very confusing, and it took me a while to figure out. Turns out Visual Studio 2010 (and perhaps prior versions) specify each model as inheriting from object.

public partial class Contact: object

This behavior is unnecessary and redundant since every object in C# already inherits from object by default. I had to go through the Auto Generated code and remove all explicit inheritance from object. After I did this the application compiled just fine. Strangely enough, now whenever I update my service reference the explicit inheritance is added back in, but does not cause an error as it did the first time. While I’d love to understand what exactly was going on with the error, it seems to have resolved and is no longer causing me issues so I’ve stopped looking into it.

The UI presented the final difficulty. We use DelegateCommands all over in our ViewModels here at InterKnowlogy and I wanted to do the same in my VMs. The problem is the underlying implementation of the DelegateCommand class, and other classes, are so different that a VM specifically designed for each framework must exist. Much of the core functionality of each VM can be shared in a base VM but each framework must still have a specific VM implementation. The idea that VMs can be reused without modification is false, but a good deal of each VM can be shared, and that’s exactly what I took advantage of.

With all of that said and done I now have a working version of Informant for WPF4 referencing a Windows Service that is installed on the same machine. The service is required so users can close the application and leave their computer on and Informant will still send all of the desired SMS messages. The Wp7.5 (Mango) version is next on my plate. This version will require me to refactor the Windows Service to support a RESTful API. The service will also need to be hosted on a publicly accessible server. My goal is to enable Wp7 users to be able to send SMS messages to their contacts and contact groups. A SL5 version will then be next available on the same server as the RESTful service.

The ability to reference SL3 libraries in the different .NET frameworks has greatly decreased the amount of work required to develop a framework specific application that fulfills the same purpose. It’s quite amazing and awesome. However, a small word of caution should be made known. The new Windows 8 WinRT framework is NOT compatible with this pattern. Each library must be a WinRT library compiled against WinRT. So I will not be able to reuse the libraries, as is, in Windows 8 WinRT. This is a huge bummer, but makes sense as I’ve learned more about what WinRT really is.

Kinect in Windows 8 on .NET Rocks

My coworker Danny Warren and I recorded a .NET Rocks session a couple weeks that just went live tonight.  We discuss how we got a Windows 8 / WinRT application to communicate with the Microsoft Kinect.  I blogged about how we pulled that off here, but check out the podcast to hear it first hand.

.NET Rocks show #714 – Dan Hanan and Danny Warren Mix Kinect and Metro

Crazy WinRT XAML Bug in Windows 8 Developer Preview

I’ve been playing with the developer preview release of Windows 8 that we got from //BUILD/.  Everyday, we find more and more “issues” that are either just straight up bugs, things that are not implemented yet, or maybe even issues that won’t be resolved because WinRT is “just different”.  This one was especially “fun” to track down – and when we did, we couldn’t believe the issue.

Start with a simple WinRT application in Visual Studio 11.  Add a class library project that will hold a couple UserControls that we’ll use in the main application.  Pretty standard stuff.

Create 2 UserControls in the library, the first one will use the other.  UserControl1 can just have some container (Grid) then use UserControl2 (which just has an ellipse).  In the main application, add a reference to the ClassLibrary and use UserControl1 in the MainPage.  Your solution should look something like this:

Solution

  <!-- MainPage.xaml -->
  ...
  xmlns:controls="using:ClassLibrary1.Controls"
  ...

<Grid x:Name="LayoutRoot"
    Background="#FF0C0C0C">
  
  <controls:UserControl1 />
  
</Grid>
  <!-- UserControl1.xaml -->
  ...
  xmlns:controls="using:ClassLibrary1.Controls"
  ...

  <Grid x:Name="LayoutRoot"
      Background="#FF0C0C0C">
    
    <controls:UserControl2 />

  </Grid>
  <!-- UserControl2.xaml -->

  <Ellipse Height="40" Width="40" Fill="Red" />

Now here’s the key step.  Add a new class to the ClassLibrary, say Class1, and have that class IMPLEMENT INotifyPropertyChanged (be sure to choose the right using statement – the one from UI.Xaml.Data).

    public class Class1 : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

That’s it.  Run it.

You will get a runtime exception:

Exception

Crazy, huh?  The Microsoft guys have confirmed this to be a known bug.  I just can’t believe what that bug would be?  How is a simple UNREFERENCED class that implements INPC getting in the way of a couple UserControls?

Ahh … the joys of coding against pre-release software…