Yet another blog about WPF, Surface, SL, MVVM, NUI....

2011

2010

 

MANGO live tile: use a picture in the IsolatedStorage as a background for your tile

3 August 2011

One on the nice feature coming with WP7's mango is "live tiles". You can create tiles directly from your application and update them from a background agent.

Here is the sample which creates a "secondary tile" for your application:

//This is a .Net class named StandardTileData
var theTile= new StandardTileData
{
Title = "Secondary Tile", //The title
BackgroundImage = new Uri("FrontImage.jpg", UriKind.Relative),
Count = 12, //Notification number
BackTitle = "Back's page title", //The title of the back page
BackContent = "A text is nice here",
BackBackgroundImage = new Uri("backImage.jpg", UriKind.Relative)
};
// Add the live tile to the Home screen (will exit the app)
ShellTile.Create(new Uri("/MainPage.xaml", UriKind.Relative), theTile);

Now, you may want to generate a screenshot of your application (using WriteableBitmap) and use it as the tile background. This is possible !

To do so, you have to store the picture in a folder named "Shared/ShellContent" otherwise you will have an NotSupportedException throwned.

The URI to use will then look like this one : "isostore:/Shared/ShellContent/background.png". You can read this MSDN page for more information.

It takes me some minutes and Wilfried to figure this out, I hope this will save you this time !
 

[UPDATED] How to call the method from the base of the base of the current class ? (base.base.MyMethod)

11 May 2011

Today I encountered a tricky need in some custom control. It was inheriting from the TabControl but I didn’t want all its feature. Especially I didn’t want it to update the SelectedContent dependency property because it was keeping a strong reference to a ViewModel and keeping it away from the garbage collector.

Continue reading...

 

VS Tip : how to locate the active document in the solution explorer using a shortcut

4 November 2010

When you have multiple projects in your solution, you often want to locate the active document in the solution explorer. There is a great option in Visual Studio which can do it for you all the time : “View.TrackActivityInSolutionExplorer”.

 

But if you do not want (as me) to turn it on all the time, there is no specific option or shortcut. So I have created a little macro which make my life easier. It simply turn on then off the option resulting by centering the active document in the solution explorer.

 

Here is the macro ( I put the Alt-T shorcut on it) :

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Public Module Utilities
Public Sub TrackProjectItem()
DTE.ExecuteCommand("View.TrackActivityInSolutionExplorer")
DTE.ExecuteCommand("View.TrackActivityInSolutionExplorer")
End Sub
End Module


Shout it kick it on DotNetKicks.com



 

Simple properties Mapper by reflection : stop copying manually each property of your objects !

8 April 2010

There is time when you have to copy each property of an object to one another. This is called mapping and it's very fastidious to do it by hand.

In this post we'll see how to create a method extension which do it for you in one line of code !

When can it be useful

Here is a non exhaustive list of usage you can find to this snippet:

  • You want to reload the previous state of an object without changing it's instance : just clone it as a snapshot and copy back the properties when you want,
  • You get's some Data Transfert Object coming from WCF/Web services and you want's to fill a specific object with this data,
  • etc ...



I surely know this is not the most efficient way to solve these problems, but this is fast to use/understand and easy to implements.

Let's jump to the code !

What's inside ? Quite a few things actually ! There is two object, the source in which we take the data and the target in which we fill in these datas.

I use reflection to obtain every property of the source and then I check on the target if a property exist with the same name. If yes I fill it with the value of the property in the source object.

I also added a filter which is a list of Property name which will be ignored by the "copy process".

With a little more time you can also add a dictionnary which may map a property name in the source to an another property name in the target if the name are note exactly the same...

public static class PropetiesMapper{
	/// <summary>
    /// Copies all the properties of the "from" object to this object if they exists.
    /// </summary>
    /// <param name="to">The object in which the properties are copied</param>
    /// <param name="from">The object which is used as a source</param>
    /// <param name="excludedProperties">Exclude these proeprties from the copy</param>
    public static void copyPropertiesFrom(this object to, object from, string[] excludedProperties)
    {
 
      Type targetType = to.GetType();
      Type sourceType = from.GetType();
 
      PropertyInfo[] sourceProps = sourceType.GetProperties();
      foreach (var propInfo in sourceProps)
      {
        //filter the properties
        if (excludedProperties != null
          && excludedProperties.Contains(propInfo.Name))
          continue;
 
        //Get the matching property from the target
        PropertyInfo toProp =
          (targetType == sourceType) ? propInfo : targetType.GetProperty(propInfo.Name);
 
        //If it exists and it's writeable
        if (toProp != null && toProp.CanWrite)
        {
          //Copty the value from the source to the target
          Object value = propInfo.GetValue(from, null);
          toProp.SetValue(to,value , null);
        }
      }
    }
 
    /// <summary>
    /// Copies all the properties of the "from" object to this object if they exists.
    /// </summary>
    /// <param name="to">The object in which the properties are copied</param>
    /// <param name="from">The object which is used as a source</param>
    public static void copyPropertiesFrom(this object to, object from)
    {
      to.copyPropertiesFrom(from, null);
    }
 
    /// <summary>
    /// Copies all the properties of this object to the "to" object
    /// </summary>
    /// <param name="to">The object in which the properties are copied</param>
    /// <param name="from">The object which is used as a source</param>
    public static void copyPropertiesTo(this object from, object to)
    {
      to.copyPropertiesFrom(from, null);
    }
 
    /// <summary>
    /// Copies all the properties of this object to the "to" object
    /// </summary>
    /// <param name="to">The object in which the properties are copied</param>
    /// <param name="from">The object which is used as a source</param>
    /// <param name="excludedProperties">Exclude these proeprties from the copy</param>
    public static void copyPropertiesTo(this object from, object to, string[] excludedProperties)
    {
      to.copyPropertiesFrom(from, excludedProperties);
    }
  }



So, do you still want to put an "Hand made" label on your object's mapping ? :-D

A more complex and complete tool

For those which wants something more powerful and complete : take a look at the automapper library on codeplex.

Shout it kick it on DotNetKicks.com



 

Sync framework - choose your primary keys type carefully

5 March 2010

Do you know the Sync Framework ? This is an amazing framework that enables roaming, sharing of data, and taking data offline !

One usage You can imagine is to sync some local clients databases with a big distant one. Each client taking its data with him and each client was abble to edit/create/delete data. synchKeys

The scenarii where the problem occurs

So where is the problem with the primary keys ? Often, when you design your database you set the types of the primary keys of each row as Int. This integer is when set as autoincremented, and everything works fine for you.

You can't do that with you wants to use the sync framework in bidirectionnal mode. Let me explain why. Imagine this scenario, where we have a database storing apples :

  1. There is 10 apples in your database and each of them is called by it's number
  2. All clients database are synched and client 1 wants to create an apple. He creates one and the apple is so called "Apple 11" : there is only 10 apples in his local database and the autoincrement rule gives him the next available number which is 11,
  3. simultanely client 2 want alsos to create an apple. He creates one and the apple is so called "Apple 11" : there is only 10 apples in his local database and the autoincrement rule gives him the next available number which is also 11,
  4. Both the clients tries to synch with the main database : there is 2" apples 11" __


Newton
What would have said Newton ? This : Auto incrementation does not work in asynchronous scenarii

Actually the data stored would have been really more complex in the real life than apples and each creation of object makes a lot of links which make this problem very complicated to solve.


The solution

As you can see the guilty part of the scenario is the auto-incrementation of the primary key. As we are in an asynchronous scenario, we can't use this pattern to create unique identifiers.Unique identifier is in fact the key of our problem : as pointed out by the MSDN the solution is to use this type instead of auto-incremented integers for the primary keys of your rows. A new value can be generated on your SQL by using NEWID() or NEWSEQUENTIALID() .

Sync framework with bi-directionnal sync ==> Use unique identifier (GUID) instead of auto-incremented integers !

Useful links



Shout it kick it on DotNetKicks.com


 

Serialize DependencyObject : it's easy !

1 March 2010

You often read on the web that the DependencyObjects are not marked as serializable and that this is a major drawback of them...



But there is a easy way to perform a serialization of these object : use XAMLWriter and XAMLReader :

public class MyDependencyObject : DependencyObject
{
public static readonly DependencyProperty MyDependencyPropertyProperty =
  DependencyProperty.Register("MyDependencyProperty", typeof(String), typeof(MyDependencyObject));
 
  public String MyDependencyProperty
  {
    get { return (String)GetValue(MyDependencyObject.MyDependencyPropertyProperty); }
    set { SetValue(MyDependencyObject.MyDependencyPropertyProperty, value); }
  }
 
}
 
...
 
MyDependencyObject obj = new MyDependencyObject();
obj.MyDependencyProperty = "One love";
String serializedString = XamlWriter.Save(obj);
Console.WriteLine(serializedString);


It will produce something like this :

<MyDependencyObject MyDependencyProperty="One love" xmlns="clr-namespace:ANTOINE.Jonathan;assembly=ANTOINE.Jonathan" />


Shout it kick it on DotNetKicks.com