Importing namespaces in Xaml for .Net for Metro Style

Importing namespaces in XAML is different in .Net Metro applications compared with WPF. The difference is subtle and caught me unawares…

In WPF, one imports a namespace using.

<Grid xmlns:Core="clr-namespace:Namespace;Assembly=AssemblyName"

This has changed to :

<Gridxmlns:Core="using:Namespace”

Note the ‘using:‘ rather than ‘clr-namespace:’

So its similar to syntax of import statements in c# code behind. The bonus is that you no longer need to specify the assembly name ( it is handled for you automatically).

System.Delegate missing Method Property in .Net for Metro Style Apps

This post is part of a series of ‘Lessons Learnt’ from  a recent conversion of Microsoft.Practices.Prism to Net Metro Prism. See  here for related posts

I got stumped on an issue with delegates whilst converting Prism to Metro  … In metro, A System.Delegate type doesn’t have a Method property. How can that be!?

Background

One of the internal classes in the Prism library (DelegateReference.cs) acts a weak Delegate reference… It takes a Delegate type parameter in its constructor and records all of its information . It then allows the delegate to be freed from memory until the point it is meant to be fired; at which point it re-creates the delegate using the information it recorded.

I believe its used as part of the EventAggregator functionality to avoid having lots of active event handlers .

Problem

The existing  constructor attempts to record the MethodInfo from the Delegate using the following line of code.

string methodName = @delegate.Method;

In .Net for Metro this Method property is not exposed

……!?

My initial thought was that the delegate must know which method to invoke; so even though it is not exposed on the abstract Delegate class; it must be recorded a private variable. Perhaps the derived class will expose the method.

So I started the debugger; and used the immediate window to inspect the delegate as it was passed to the ctor.

clip_image001

Notice that you can see the Method property – [void DoEvent(System.String).

If I look at the base System.Delegate class then I can also see the same method:

clip_image002

The property is there and i can see the event. Yet intellisense and the compiler won’t allow me to access it.

…..!? Does anyone know what is causing this?

My initial thought is that there is a mismatch between the assemblies that Visual Studio/Compiler is using; and those that are in use from the GAC at runtime.

Workaround

Instead of using a strongly typed Delegate; I referred to it using the dynamic keyword instead. This avoids the compiler checking; and allows me to write the code that queries the method property. As the Method property is in memory when running the app the code works as it should.

Error after upgrading to Wcf Data Service 5.0

I recently upgraded a WCF Data Service project to WCF Data Services 5.0  for OData v3. This upgrade has support for accessing your EF Code First entities via a Wcf data service.

There’s a good blog post on MSDN by Glenn Gailey with details on how to upgrade.

However, I started my upgraded service and got this rather unhelpful error message:

The server encountered an error processing the request. Please see the service help page for constructing valid requests to the service. The exception message is ‘On data context type ‘<type>’, there is a top IQueryable property ‘<propertyName>’ whose element type is not an entity type. Make sure that the IQueryable property is of entity type or specify the IgnoreProperties attribute on the data context type to ignore this property.’. See server logs for more details.

The cause of the problem was failing to remove all references to  System.Data.Services and System.Data.Services.Client from all my projects.

Following the guidance I’d removed all references to System.Data.Services.* from the main WCF data service project; but I had missed the indirect reference in my “Entity Model” Project.  Some entities  were marked with the [DataContractKey()] attribute; thus leading to the stray reference.

Removing all reference to System.Data.Service.* and replacing with Microsoft.Data.Services.Client.dll fixed the error.

(assemblies can be found in %programfiles(x86)%\Microsoft WCF Data Services\5.0\bin)

Where is Type.GetTypeInfo() in .Net 4.5/Metro apps?

This post is part of a series of ‘Lessons Learnt’ from  a recent conversion of Microsoft.Practices.Prism to Net Metro Prism. See  here for related posts

Where is Type.GetTypeInfo()!?

Most members from the System.Type class have been moved to the System.Reflection.TypeInfo class. All the documentation suggests you can get an instance of this type calling Type.GetTypeInfo(); but its not there?

>> Its an extension method and to use it you must include an import statement to System.Reflection:

using System.Reflection

Doh!

Where are .Net Metro apps deployed and installed to?

The exe and assemblies can be found under C:\Program Files\WindowsApps  (need to add permissions to view folder)

Deployed Metro apps access application settings and runtime state information in C:\Users\<username>\AppData\Local\Packages

The  appxmanifest.xml can be found under C:\ProgramData\Microsoft\Windows\AppRepository  (need to add permissions to view folder)

 

Your application can be identified by matching the folder name with the name you provided in the Package.appxmanifest file included in your project.

Open Solution Explorer –> Package.appxmanifest:

image_thumb3

Open the Packaging Tab:

image_thumb1

In File Explore navigate to C:\Users\user\AppData\Local\Packages. –> Locate folder via name

image_thumb6

Resources (.resw) and ResourceLoader in .Net for Metro Style Apps

This post is part of a series of ‘Lessons Learnt’ from  a recent conversion of Microsoft.Practices.Prism to Net Metro Prism. See  here for related posts

In Metro there is a whole new improved mechanism for dealing with resources and localization. Its quite powerful; allowing one to embed text, images  and even Resource-Dictionaries that can vary from one locality to another.

If you’re used to Resource.resx files (for specific language/culture);  then you may be surprised to find its not an option with Metro Apps.  Instead the new file type is a Resource.resw that allows one to enter String Resources.

A quick web search of this new resource file gave me the wrong impression of how to do localization in Metro. Many forums commented on the lack of the usual auto generated code to access resources. Most suggested avoiding ResourceManager and using ResourceLoader. Others commented that embedding localized image resources in metro is not supported.

It true that the new preferred way of loading resources is using the ResourceLoader class

A number of code snippets show the following code:

ResourceLoader rl = new ResourceLoader("MyAssembly/Resources"); string localizedString = rl.GetString("MyLocalizedStringKey");  

This code will access any resources you add to “MyAssembly/Resources.resw”   

….but I was left a little confused. How do I know the path to specify for my Resource file?   How can I swap between different languages using this? I also wanted to know how to change images based on the current language of the user.

Fortunately I kept looking and came across this 3 part blog post, Part 1, Part 2and Part 3 – that do an excellent job of explaining it all.

Basically you organise you’re solution so that it contains folders for specific language codes. For example:

image

You add a resources.resw into each folder and put the appropriate language variants in each

You simply create an instance of ResourceLoader without passing a specific resource file into the ctor:

ResourceLoader rl = new ResourceLoader(); string localizedString = rl.GetString("MyLocalizedStringKey");

And voila, you app will magically have the correct language based on your windows language settings. (To understand the magic, read Part 2and Part 3)

You can access the current User’s language choice using Windows.System.UserProfile.GlobalizationPreferences.Languages. This returns the list of language choices (a user can have a order (or fallback) of preferred languages). The most preferred language is first in the list.

var languages = Windows.System.UserProfile.GlobalizationPreferences.Languages; string preferredLanguage = languages.ToList()[0];

Images (and other Assets) work in exactly the same manner. Just name a folder after the language code you’re catering for and add similar resources into it. See below

image

Note:

  • Do use an appropriate language code (en-GB, fr-FR)
  • Do use a consistent name for assets in each language folder (flag)
  • Do remember case sensitivity (it has to be consistent)

Now to use my localised flag.png file I simply use the following line of code:

myImageControl.Source = new BitmapImage(new Uri(@"ms-appx:/Assets/flag.png"));

Notice that I do not refer to a specific file in my application; simply the assets folder.

Also notice the use of ms-appx: – In metro you cannot use relative Uri to a resource – it must be absolute. ms-appx:  is equivalent of using [packagename]

So now I could vary my application based on the users preferred language. As the user changes between English (en-GB) and French (fr-FR) language, the application automatically updates the greeting and the  flag displayed:

image image

To automatically respond to a user changing language (cos that happens every day), there is an event that you can subscribe to.

var manager = Windows.ApplicationModel.Resources.Core.ResourceManager.Current; manager.DefaultContext.QualifierValues.MapChanged += QualifierValues_MapChanged;

 

If anyone wants the source code for this app; then let me know and I’ll make it available

Converting Prism to .Net for Metro Style Apps

I recently converted Prism to work with .Net for Metro Style Apps.

You can get the project on codeplex at http://metroprism.codeplex.com/ 

Its a pragmatic conversion; but keeps most of the existing functionality that you get in Prism 4.1 apart from features that don’t naturally work within Metro (such as reflectively loading modules). I’ve kept the namespaces intact; so its easy to replace with the official Prism framework when it is ready. However, I have renamed the assemblies to avoid any confusion.

It uses a MetroIoC  – (port from microIoc  done by Ian Randall) as the only IOC container I could find to work with Metro style apps.

My aim was :

  • Get a functioning Prism framework to help create a modular Metro App (…and to help convert some desktop apps I’ve created using Prism 4.1)
  • Learn the differences between .Net 4.0 and .Net for Metro Style Apps
  • Learn the pitfalls of moving apps from the Desktop to Metro

I’ll write up a few posts with details of the conversion and a few lessons learnt.

I’ll aggregate in this post and on codeplex at http://metroprism.codeplex.com/documentation

Resources (.resw) and ResourceLoader in .Net for Metro Style Apps

Where is Type.GetTypeInfo() in .Net 4.5/Metro apps?

System.Delegate missing Method Property in .Net for Metro Style Apps

Accessing Team Information using Team Foundation 11 SDK

Written against Visual Studio/Team Foundation beta; so subject to any changes in the SDK.

Team Foundation Server 11 has the notion of teams; and its possible to assign work and iterations to multiple teams within a single Team Project.

I was searching for  a way to access the Team information via the Microsoft.TeamFoundation.Client  API and stumbled over the TfsTeamService class.

Add a reference to Microsoft.TeamFoundation.Client.dll.

Note: The tfs assemblies can be found either in the GAC or under the folder  %programfiles%\Microsoft Visual Studio 11.0\Common7\IDE

Create a connection to TFS project collection:

Uri collectionUri = new Uri(@"http://<server>:8080/tfs/<tpcName>");                         TfsTeamProjectCollection tfsConnection=                new TfsTeamProjectCollection(collectionUri, new UICredentialsProvider());

Create an instance of the TfsTeamService class and call the Initialize method passing in the connection

    TfsTeamService teamService = new TfsTeamService();     teamService.Initialize(tfsConnection);

You now must query the Team Information by calling a method on the TfsTeamService instance. There are 3 possible methods to use:

//The project URI - this is the identifier for the Team Project you're looking within. 
//To retrieve the project URI you need to iterate the team projects - see TFS 2010 on MSDN 
 string projectUri  
          = @"vstfs:///Classification/TeamProject/7356cf03-278b-4b04-8915-eb50d29665ca"; 

//1. Returns the default team in the Team Project
TeamFoundationTeam defaultTeam = teamService.GetDefaultTeam( 
                projectUri,  
                new List<String>() 
                );     

//2. Returns a specific team in the Team Project based on the teamname parameter provided
TeamFoundationTeam specificTeam = teamService.ReadTeam( 
                projectUri, 
                "TeamName", 
                new List<String>() 
                );  

//3. Returns all the teams in the Team Project
IEnumerable<TeamFoundationTeam> allTeams = teamService.QueryTeams(projectUri);

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

 

Now that you have the Team Information you can access it properties as expected. For example to console output a list of members in a team you can use:

TeamFoundationIdentity[] teamMembers=   team.GetMembers(tfsConnection, MembershipQuery.Expanded);                         foreach (var member in teamMembers) {                   Console.WriteLine("  {0}", member.DisplayName);     foreach (var item in member.GetProperties())     {          Console.WriteLine("       {0}: {1}", item.Key, item.Value);                       }             
}

Local SharePoint Deployment + Unit Testing == Frustrating Mix

I’ve been working on a small SharePoint project this week. I have a single machine setup -  I’m developing in Visual Studio and deploying to a local installation of SharePoint

I set about writing the code, unit testing it and then deploying it into SharePoint.   However when I came to re-run the unit tests (after deployment) I got the following error:

Exception: System.MissingMethodException: Method not found

This was slightly baffling exception. The method existed…I’d just added it.

After a couple of sanity checks; I realised the tests weren’t using the local version of my assembly. It was reading it from the GAC. The act of deploying the solution to SharePoint had installed the assembly on my behalf.

I uninstalled the assembly from the GAC via the VS command prompt using:

Gacutil /u “assemblyName”

This fixed the problem but causes a re-occurring issue every time I deploy to SharePoint.

 

A couple of options that may help around the re-occurring issue (Granted none of these are ideal) :

1. Add the assembly reference to the test project as a file reference rather than as a project reference. <Yuck>

2. Remove the assembly from the GAC as part of a pre-build event of the test project. This will work but clearly will make your deployed SharePoint solution screwy.

3. Increment the assembly version number in AssemblyInfo.cs after you deploy to SharePoint. <I could imagine this being frustrating for a team setup and someone checks the version number in by mistake.>

 

If anyone has a better workaround or a way to avoid the problem then let me know

Xml Validation error when inserting paragraphs in multi-line text box controls in Word 2007

Recently whilst developing a VSTO document template, I was presented with this error whilst attempting to re-open a saved document.

‘The Office Open XML File <documentname>.docx cannot be opened because there are problems with the contents.

Unspecified error. Location: Part: /word/document.xml, Line: 2, Column: 1054’

Word offered to recover the unreadable content; but subsequently saving and re-opening resulted in the same error. I unzipped the docx file and opened the contents into an editor to discover what was breaking it…

Word 2007 allows developers to use textbox controls to position/format specific text regions within a document template. The control provides a handy way of accessing this region from code behind.

The textbox control also provides multi-line capabilities; but in the form of new lines rather than ‘Paragraph’ breaks. You can see this by turning on symbols within word:

TextBoxControl

Notice, within the text box control, pressing return inserts a newline rather than a new paragraph. Outside the control it inserts a new paragraph.

However, this protection provided by the Word UI is not enforced when programmatically setting the text. It allows the following to happen:

image

This has no noticeable effect whilst in the document. However, once you save and re-open you’ll have stumbled onto a nasty bug with no obvious way of back-tracking to the cause. The representation of the paragraph in xml actually acts as the closing tags for the textbox xml block, causing the above error.

To avoid the error, I simply changed the text string; separating newlines with ‘\v’ [rather than StringBuilder.AppendLine()]. If I’d been unable to do that then I would have investigated the word API for a method to format the text.

To fix the broken document you can either

  1. Manually fix the broken xml file
  2. Allow Word to recover the document, remove the paragraph spacing and resave the document

This bug appears to be fixed in MS Word 2010.