Serializing Cyclic Graphs of objects with WCF

*** This is a repost of a previous post because of moving to a new blog engine in which some formatting was lost ***

Abstract

In this blog post I will be discussing how the serialize cyclic graphs of objects using WCF, including data contracts and POCO’s ( Plain Old CLR Objects).

Introduction

WCF allows you to serialize any number of objects over the network or to disk using the DataContractSerializer class. However, some issues can arise when you have cycles in your object graph, and especially when you want some shared objects to stay shared!

Serializing cyclic objects

Let’s look at this with a couple of examples. First I want some datacontracts with possible cycles:

  [DataContract(Namespace=Namespaces.U2U, Name="address", IsReference=false)]
  public class Address
  {
    [DataMember(Name="street", Order=1)]
    public string Street { get; set; }
    [DataMember(Name="city", Order=2)]
    public string City { get; set; }
  }

  [DataContract(Namespace = Namespaces.U2U, Name = "person", IsReference = false)]
  public class Person
  {
    [DataMember(Name="name", Order=1)]
    public string Name { get; set; }
    [DataMember(Name="age", Order=2)]
    public int Age { get; set; }
    [DataMember(Name="partner",Order=3)]
    public Person Partner { get; set; }
    [DataMember(Name = "address", Order = 4)]
    public Address Address { get; set; }
  }

 

I’ll create a person object with a reference to another person. Since they are partners, they will point to each other.

image

DataContractSerializer ser = new DataContractSerializer(typeof(Person));
string path = Path.Combine( Environment.CurrentDirectory, "cartoon.xml" );
using (FileStream ms = File.Open(path, FileMode.Create, FileAccess.Write))
{
  Address home = new Address { Street = "ToonLane", City = "ToonTown" };
  Person tom = new Person { Name = "Tom", Age = 4, Address = home };
  Person jerry = new Person { Name = "Jerry", Age = 2, Address = home };
  tom.Partner = jerry;
  jerry.Partner = tom;
  ser.WriteObject(ms, tom);
}

So what happens when you try this? You’ll get an exception:

image

[NOTE: By the way, this is much better then in .NET 1.0 with the XmlSerializer, it would serialize the first object, then follow the link to the second, then back the to first, then back to the second, until your disk ran out of space :) Now XmlSerializer will also throw an exception if you try to serialize cycles.]

Using IsReference

To make the exception go away, you add IsReference=true to the Person’s DataContract:

The result now looks like this:

<person z:Id="i1" 
xmlns="urn://www.u2u.be/samples/wcf/2009"
xmlns:i=http://www.w3.org/2001/XMLSchema-instance
xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/"> <name>Tom</name> <age>4</age> <partner z:Id="i2"> <name>Jerry</name> <age>2</age> <partner z:Ref="i1"/> <address> <street>ToonLane</street> <city>ToonTown</city> </address> </partner> <address> <street>ToonLane</street> <city>ToonTown</city> </address> </person>

Look how Jerry refers back to Tom using the z:Ref! Now you can easily send objects with cycles. But wait! Both point to the same address, but now Tom and Jerry both have an address, although identical.

image

Again we can change this by changing the IsReference to true in the Address DataContract. Now the result looks like this:

<person z:Id="i1" xmlns="urn://www.u2u.be/samples/wcf/2009" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
  <name>Tom</name>
  <age>4</age>
  <partner z:Id="i2">
    <name>Jerry</name>
    <age>2</age>
    <partner z:Ref="i1"/>
    <address z:Id="i3">
      <street>ToonLane</street>
      <city>ToonTown</city>
    </address>
  </partner>
  <address z:Ref="i3"/>
</person>

Please note that now both Tom and Jerry use the same address instance, not clones.

Serializing cyclic POCO’s with WCF

“And what about POCO’s? (Plain Old Clr Objects) I hear you say. Well in that case you cannot attach the DataContract attribute of course, so you‘ll need to use another variant of the DataContractSerializer constructor:

new DataContractSerializer(typeof(PocoPerson), null, int.MaxValue, false
                          , /* preserveObjectReferences */ true, null, null);

So, using this constructor the previous example looks like this:

  public class PocoPerson
  {
    public string Name { get; set; }
    public int Age { get; set; }
    public PocoPerson Partner { get; set; }
    public PocoAddress Address { get; set; }
  }

  public class PocoAddress
  {
    public string Street { get; set; }
    public string City { get; set; }
  }
  DataContractSerializer ser = 
    new DataContractSerializer(typeof(PocoPerson), null, int.MaxValue, false
                              , /* preserveObjectReferences */ true, null, null);
  string path = Path.Combine(Environment.CurrentDirectory, "cartoon2.xml");
  using (FileStream ms = File.Open(path, FileMode.Create, FileAccess.Write))
  {
    PocoAddress home = new PocoAddress { Street = "ToonLane", City = "ToonTown" };
    PocoPerson tom = new PocoPerson { Name = "Tom", Age = 4, Address = home };
    PocoPerson jerry = new PocoPerson { Name = "Jerry", Age = 2, Address = home };
    tom.Partner = jerry;
    jerry.Partner = tom;
    ser.WriteObject(ms, tom);
}

Running this will result in following Xml:

<PocoPerson z:Id="1" 
            xmlns="http://schemas.datacontract.org/2004/07/ReferenceSerialization" 
            xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
  <Address z:Id="2">
    <City z:Id="3">ToonTown</City>
    <Street z:Id="4">ToonLane</Street>
  </Address>
  <Age>4</Age>
  <Name z:Id="5">Tom</Name>
  <Partner z:Id="6">
    <Address z:Ref="2" i:nil="true"/>
    <Age>2</Age>
    <Name z:Id="7">Jerry</Name>
    <Partner z:Ref="1" i:nil="true"/>
  </Partner>
</PocoPerson>

Using a custom behavior

Of course it is not that easy to use this contructor inside a real service, because you’re not in charge of creating the serializer. But hey, WCF is very extensible right? So to plug the hole, you need to build your own Behavior, specifically a DataContractSerializerOperationBehavior.

public class CyclicSerializationBehavior : DataContractSerializerOperationBehavior
{
  public CyclicSerializationBehavior(OperationDescription od)
    : base(od)
  { }

  private const bool preserveObjectReferences = true;

  public override XmlObjectSerializer CreateSerializer(
Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes) { return new DataContractSerializer(type, name, ns, knownTypes,
this.MaxItemsInObjectGraph, this.IgnoreExtensionDataObject,
preserveObjectReferences, this.DataContractSurrogate); } public override XmlObjectSerializer CreateSerializer(
Type type, string name, string ns, IList<Type> knownTypes) { return new DataContractSerializer(type, name, ns, knownTypes,
this.MaxItemsInObjectGraph, this.IgnoreExtensionDataObject,
preserveObjectReferences, this.DataContractSurrogate); } }

To get this behavior installed you need to write some code to add it the the operation’s behavior, or even better is to use an IContractBehavior:

  [AttributeUsage(AttributeTargets.All)]
  public class CyclicSerializationAttribute : Attribute, IContractBehavior
  {
    public void AddBindingParameters(ContractDescription contractDescription, 
ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ContractDescription contractDescription,
ServiceEndpoint endpoint, ClientRuntime clientRuntime) { ReplaceDataContractSerializerOperationBehavior(contractDescription); } public void ApplyDispatchBehavior(ContractDescription contractDescription,
ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) { ReplaceDataContractSerializerOperationBehavior(contractDescription); } private void ReplaceDataContractSerializerOperationBehavior(ContractDescription contractDescription) { foreach (OperationDescription operation in contractDescription.Operations) { DataContractSerializerOperationBehavior beh =
operation.Behaviors.Find<DataContractSerializerOperationBehavior>(); if (beh != null) { operation.Behaviors.Remove(beh); operation.Behaviors.Add(new CyclicSerializationBehavior(operation)); } } } public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) { } }

I made this class into an attribute so you can apply it to your service contract or service class, and when WCF loads it it replaces the default DataContractSerialerOperationBehavior. At first I simply added it to the collection of behaviors, but then I got all kinds of strange things :)

So, to use this now you apply the attribute to the service contract:

  [ServiceContract]
  [CyclicSerializationAttribute]
  public interface ICyclicSerializationService
  {
    [OperationContract]
    PocoPerson GetPocoPerson();
  }

Don’t forget, you should add this to both the server en client side.

Comments (73) -

  • Chocolate Ice Cream Recipes

    12/18/2009 4:46:09 AM |

    When I originally commented I clicked the "Notify me when new comments are added" checkbox and now each time a comment is added I get four emails with the same comment.
    Is there any way you can remove me from that service?
    Thanks!

  • Hard Candy Recipes

    12/18/2009 9:51:24 AM |

    Do you accept guest posts? I would love to write couple articles here.
    I was wondering what is up with that weird gravatar??? I know 5am is early and I'm not looking my best at that hour, but I hope I don't look like this! I might however make that face if I'm asked to do 100 pushups. lol

  • set up a company

    12/19/2009 7:28:46 AM |

    Nice to be visiting your blog again, it has been months for me. Well this article that i've been waited for so long. I need this article to complete my assignment in the college, and it has same topic with your article. Thanks, great share.

  • pool solar panels

    12/22/2009 10:33:22 AM |

    Excellent read, I just passed this onto a colleague who was doing a little research on that. And he actually bought me lunch because I found it for him smile So let me rephrase that: Thanks for lunch!

  • barcode mobile scanner

    12/22/2009 11:12:22 AM |

    Me and my friend were arguing about an issue similar to this! Now I know that I was right. lol! Thanks for the information you post.

  • Bredbånd priser

    1/7/2010 2:04:50 PM |

    Dude.. I am not much into reading, but somehow I got to read lots of articles on your blog. Its amazing how interesting it is for me to visit you very often.

  • alen air purifier

    1/9/2010 11:42:32 PM |

    This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work.

  • Valentines Day 2010

    1/13/2010 2:38:57 AM |

    Keep 'em coming... you all do such a great job at such Concepts... can't tell you how much I, for one appreciate all you do!

  • out of body experience

    1/15/2010 3:48:28 AM |

    This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work.

  • Abdominal Exercises

    1/15/2010 10:30:23 AM |

    Me and my friend were arguing about an issue similar to this! Now I know that I was right. lol! Thanks for the information you post.

  • IT support

    1/18/2010 11:43:15 PM |

    The blog was absolutely fantastic! Lots of great information and inspiration, both of which we all need!

  • pay day loans

    1/25/2010 2:04:56 PM |

    Do not save your loving speeches For your friends till they are dead; Do not write them on their tombstones, Speak them rather now instead.

  • sugar babys

    1/25/2010 3:58:15 PM |

    This is such a great resource that you are providing and you give it away for free. I love seeing websites that understand the value of providing a quality resource for free. It is the old what goes around comes around routine. Did you acquired lots of links and I see lots of trackbacks??

  • Electric Train Sets

    1/31/2010 2:25:22 PM |

    I was very pleased to find this site.I wanted to thank you for this great read!! I definitely enjoying every little bit of it and I have you bookmarked to check out new stuff you post.

  • cash loans

    2/3/2010 3:51:09 PM |

    Work is not man's punishment. It is his reward and his strength and his pleasure.

  • payday loans

    2/3/2010 3:51:18 PM |

    Believe in yourself, never give up and go about your business with passion drive and enthusiasm.

  • online personal loans

    2/4/2010 11:20:41 PM |

    Success usually comes to those who are too busy to be looking for it.

  • pay day loans

    2/4/2010 11:20:51 PM |

    One that would have the fruit must climb the tree.

  • seo packages

    2/5/2010 4:22:06 AM |

    Me and my friend were arguing about an issue similar to this! Now I know that I was right. lol! Thanks for the information you post.

  • seo packages

    2/5/2010 11:09:12 AM |

    Me and my friend were arguing about an issue similar to this! Now I know that I was right. lol! Thanks for the information you post.

  • juicer machine

    2/8/2010 7:23:54 PM |

    This article gives the light in which we can observe the reality. this is very nice one and gives indepth information. thanks for this nice article

  • teeth whitening

    2/9/2010 9:08:15 AM |

    It is better to err on the side of daring than the side of caution.

  • indoor gardening

    2/10/2010 8:17:36 AM |

    Howdy, i read your blog occasionally and i own a similar one and i was just wondering if you get a lot of spam comments? If so how do you prevent it, any plugin or anything you can advise? I get so much lately it's driving me mad so any assistance is very much appreciated.

  • low carb foods diet

    2/13/2010 7:09:47 AM |

    Took me time to read all the comments, but I really enjoyed the article. It proved to be Very helpful to me and I am sure to all the commenters here! It's always nice when you can not only be informed, but also entertained! I'm sure you had fun writing this article.

  • nitrogen tank

    2/15/2010 2:37:03 AM |

    Just wanted to give you a shout from the valley of the sun, great information. Much appreciated.

  • Wealthy Affiliate Scam

    2/26/2010 1:47:56 AM |

    Couldn?t be written any better. Reading this post reminds me of my old room mate! He always kept talking about this. I will forward this article to him. Pretty sure he will have a good read. Thanks for sharing!

  • aion guide

    2/28/2010 5:29:13 AM |

    Just wanted to give you a shout from the valley of the sun, great information. Much appreciated.

  • SEO Package

    2/28/2010 9:31:02 PM |

    Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon.

  • umbrella payroll

    2/28/2010 10:12:28 PM |

    Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon.

  • Calvin Guevarra

    3/9/2010 5:20:03 AM |

    Great site, where did you come up with the information in this posting? I'm pleased I found it though, ill be checking back soon to see what other articles you have.

  • Jacques Raglin

    3/15/2010 9:46:04 PM |

    This is a very intriguing post, I was looking for this info. Just so you know I located your blog when I was researching for blogs like mine, so please check out my site sometime and leave me a comment to let me know what you think.

  • how to get a six pack fast

    10/21/2011 7:51:06 AM |

    Thank you my friend for taking the time here to really show me the ropes in terms of getting ahead in life and really helping me be the best person that I can possibly be.

  • jonny rocxker

    10/21/2011 7:53:16 AM |

    Thank you my friend for <a href="howtogetasixpackfasthq.org/.../how-to-get-a-six-pack-fast">how to get a six pack fast</a> taking the time here to really show me the ropes in terms of getting ahead in life and really helping me be the best person that I can possibly be.

  • jon rocker

    11/2/2011 3:01:18 AM |

    My friend I really believe that the [url=http://howtoloselegfatnow.com/]how to lose leg fat[/url] world is yours if you work really hard and if you just work at achieving and focusing on exactly what it is that you want. So thank you very much.

  • sizegenetics member login

    4/13/2013 4:26:07 AM |

    I  effectively   advise  all the  to say  I 'm  initiate  right through to  weblog  also now   surplus  dear  true  web site .  Virtually all   inclined  Im planing to bookmark  onto the  site . You definitely  have exceeding   well crafted articles . Bless  the  huge undertaking  for  divvying  sharp   fx  us the website   insurance.

  • Bryce Luthy

    12/2/2013 1:42:55 AM |

    |

  • Hack Like Facebook

    1/15/2014 5:46:33 PM |

    Great video, Fun and succinctly explained.. Will use it an introduction when I am giving talks to genealogists and historians on blogging

  • Hack Like Facebook

    1/17/2014 6:30:35 AM |

    Great video, Fun and succinctly explained.. Will use it an introduction when I am giving talks to genealogists and historians on blogging

  • Aldo Hites

    2/7/2014 1:52:41 AM |

    Absolutely pent subject matter, appreciate it for selective information .

  • Burton Haynes

    2/7/2014 6:37:38 AM |

    Saved as a favorite, I like your website!

  • more info

    2/9/2014 2:17:43 AM |

    The Muscle Maximizer is state of art nutritional software created qualified nutrition expert and fitness trainer Kyle Leon.

  • Werner Winkeljohn

    2/11/2014 12:43:11 PM |

    Absolutely pent subject matter, appreciate it for selective information .

  • how to activate windows 7 ultimate 64 bit genuine product key

    3/6/2014 2:16:25 AM |

    Hey Thanks For Making And Sharing The Very Entertaining Blog Post Keep Up The Amazing Work! I Posted A Back Link To My Win 7 Ultimate 64 Bit Key Posts To Share With You How I Activate Windows 7 Enjoy!

  • Article Spinning Service

    3/7/2014 1:32:26 AM |

    Great post. I was checking constantly this blog and I'm impressed! Very helpful info specially the last part Smile I care for such information much. I was seeking this particular info for a long time. Thank you and best of luck.

  • Phone Numbers

    3/17/2014 8:24:31 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Phone Numbers

    3/21/2014 12:51:55 AM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Phone Numbers

    3/25/2014 10:30:55 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Phone Numbers

    4/3/2014 9:24:59 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Phone Numbers

    4/6/2014 8:23:25 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Gregory Despain

    4/7/2014 12:19:35 PM |

    I simply want to say I'm all new to blogs and honestly savored you're web page. Very likely I’m likely to bookmark your website . You surely come with very good stories. Kudos for revealing your webpage.

  • Phone Numbers

    4/10/2014 8:27:24 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Julieta Raisch

    4/11/2014 10:29:18 PM |

    Sorry for the huge review, but I'm really loving the new Zune, and hope this, as well as the excellent reviews some other people have written, will help you decide if it's the right choice for you.

  • Roy Deltufo

    4/14/2014 2:47:52 AM |

    I love this show! Thank you so much, Amy!

  • Phone Numbers

    4/14/2014 6:58:14 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Adan Schnurr

    4/14/2014 8:47:23 PM |

    You made some Good points there. I did a search on the topic and found most people will agree.

  • Phone Numbers

    4/15/2014 11:11:27 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Phone Numbers

    4/15/2014 11:18:02 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Phone Numbers

    4/16/2014 11:39:28 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Phone Numbers

    4/21/2014 11:44:08 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Kittie Geathers

    4/26/2014 5:18:19 AM |

    Sorry for the huge review, but I'm really loving the new Zune, and hope this, as well as the excellent reviews some other people have written, will help you decide if it's the right choice for you.

  • Phone Numbers

    4/27/2014 11:34:31 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Phone Numbers

    4/28/2014 9:06:25 PM |

    The Numbers Helpline has sourced 1000's of customer service contact <a href="www.numbershelpline.co.uk/.../";>Phone numbers</a> in the UK. We know how hard it can be to find those <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> at times that why we have made a directory with them all in one place so you will never have waste long periods of time looking for a customer service contact <a href="www.numbershelpline.co.uk/.../";>Phonenumbers</a> again.

  • Kraig Sengupta

    5/8/2014 4:24:57 AM |

    Hey it seems to be great content also share up this awesome from my side. <a href=”http://mothersday2014poemssongs.in/”>Mothers Day 2014</a>

  • Corey Nasalroad

    5/8/2014 4:34:08 AM |

    Hey it seems to be great content also share up this awesome from my side. <a href=”http://mothersdaywishes2014.in/”>Mothers Day 2014</a>

  • Fred Territo

    5/8/2014 4:36:26 AM |

    Thnks for such a nice article i am also having something great for you.<a href=”http://mothersday2014poemssongs.in/”>Mothers Day 2014</a>

  • activate windows 7 ultimate 64

    5/11/2014 7:18:09 PM |

    Hey Thank Ya For Making And Sharing This Very Entertaining Blog Post Keep Up The Good Work!!! I Posted A Back Link To My Activate Windows Page To Show You How To Activate Windows Enjoy!

  • activate windows 7 ultimate

    5/13/2014 6:38:44 AM |

    Hey Thank Ya For Creating This Very Educational Post Keep Up The Amazing Work!!! I Left A Back Link To My Activate Windows Page To Share With You How To Activate Windows 7 Ultimate 64 Bit! Enjoy!

  • activate windows 7 ultimate 64

    5/16/2014 8:04:41 PM |

    Hey Thank Ya For Creating And Sharing This Very Useful Weblog Post Keep Up The Great Work. I Left A Back Link To My Activate Windows 7 Ultimate 32 Bit Pages To Share With You How To Activate Windows 7 Ultimate! Check Out My How To Install Microsoft Windows 7 Guides Web Log. Enjoy!!!

  • Tomeka Sundeen

    5/17/2014 11:00:45 PM |

    Pretty great info.Thanx for sharing.There aren't any softwares on the market that could crack a fb account.Nevertheless i possess a one which would help anyone to un-lock any facebook account without much trouble.You can check it under.

  • Yung Pulkrabek

    5/18/2014 9:41:08 PM |

    Great – I should definitely pronounce, impressed with your website. I had no trouble navigating through all the tabs as well as related info ended up being truly easy to do to access. I recently found what I hoped for before you know it at all. Reasonably unusual. Is likely to appreciate it for those who add forums or something, website theme . a tones way for your client to communicate. Nice task.

  • Burton Haynes

    5/25/2014 11:02:54 AM |

    I just want to mention I am just new to blogging and definitely liked your web blog. Almost certainly I’m going to bookmark your blog post . You definitely have impressive posts. Thanks a bunch for sharing with us your blog site.

  • Burton Haynes

    5/28/2014 3:26:45 PM |

    I just want to say I am just very new to weblog and seriously enjoyed you're page. Probably I’m likely to bookmark your blog . You absolutely come with exceptional writings. With thanks for revealing your web page.

  • Tyson F. Gautreaux

    5/29/2014 3:36:33 PM |

    I just want to tell you that I am newbie to blogs and honestly savored your web page. Probably I’m likely to bookmark your site . You absolutely come with good articles and reviews. Cheers for sharing your website page.

  • Issac Maez

    6/9/2014 2:31:40 AM |

    Great work on your getting cut information. Very helpful. Thankyou.

  • discover for more

    6/12/2014 11:49:29 AM |

    I would like to thnkx for the efforts you've put in writing this website. I'm hoping the same high-grade website post from you in the upcoming as well. Actually your creative writing abilities has encouraged me to get my own web site now. Really the blogging is spreading its wings quickly. Your write up is a great example of it.

  • navigate to this website

    7/3/2014 7:56:29 PM |

    I just want to say I am just new to blogs and truly loved you're blog. Probably I’m likely to bookmark your site . You absolutely come with wonderful articles. With thanks for sharing with us your webpage.

  • William Perking

    7/6/2014 3:59:55 PM |

    Veery good info. Lucky me I recently found your site by chance (stumbleupon). I've book-marked it for later!

  • Dante Sotak

    7/19/2014 7:46:40 AM |

    "Enter YourName@YourKeywords in the Name field to take advantage"

  • Dante Sotak

    7/19/2014 7:47:02 AM |

    "The content of this field is kept private" "Switch to plain text editor" -inurl:register

  • Annett Debuhr

    7/19/2014 7:47:03 AM |

    "powered by byteflow" "You can use Markdown here"

  • Rosana Losneck

    7/19/2014 9:50:38 AM |

    "powered by pMachine" "Notify me when someone replies to this post"

  • Elmer Liebenow

    7/19/2014 9:51:17 AM |

    "comment moderation is enabled and may delay your comment"

  • Carey Woelfel

    7/19/2014 9:51:45 AM |

    "This site uses KeywordLuv."

  • Jeramy Slavis

    7/19/2014 10:03:53 AM |

    "Komentiraj" "Nijedan komentar do sada."

  • Synthia Nattiah

    7/19/2014 10:04:01 AM |

    "Powered by BlogEngine"

  • Vito Donze

    7/20/2014 2:58:52 AM |

    "Theme by Mads Kristensen"

  • Terrell Curlis

    7/20/2014 2:59:03 AM |

    "Emër:" "Postë (nuk do të botohet)" "Website" "(e domosdoshme)"

  • Sindy Rieke

    7/20/2014 3:19:31 AM |

    "Add comment" Name "E-mail" Website Comment Preview "Notify me when new comments are added"

  • Dante Sotak

    7/20/2014 3:19:40 AM |

    "Powered by !JoomlaComment"

  • Samara Swainston

    8/5/2014 4:10:23 AM |

    Great site. Lots of helpful info here. I am sending it to a few friends ans also sharing in delicious. And naturally, thanks on your sweat!

  • Mira aquí ahora

    8/5/2014 3:33:52 PM |

    Muchas gracias por los consejos, yo buscó que los temas sean de calidad. un saludos y besos.

  • kaceylu

    8/5/2014 8:26:42 PM |

    I found the entire Software Tailor team to very helpful and knowledgeable.
    You help me understand the differences between the other systems on the market
    and the <a href="http://www.softwaretailor.com";>software development</a>

  • kaceylu

    8/5/2014 8:27:10 PM |


    We are very happy with http://www.softwaretailor.com. They are reliable, responsive and extremely
    customer focused.

  • kaceylu

    8/5/2014 8:27:53 PM |


    China English Tour is the largest tour club in China.With decades of travelling experience,
    our club offers the most comprehensive tours, from group packages, tailor-made private itineraries
    to hotel, flight and train ticket booking services. Our club members are ready to help you.
    please find http://www.chinaenglishtour.com

  • kaceylu

    8/5/2014 8:28:53 PM |


    China English Tour is the largest tour club in China.With decades of travelling experience,
    our club offers the most comprehensive tours, from group packages, tailor-made private itineraries
    to hotel, flight and train ticket booking services. Our club members are ready to help you.
    please find http://www.chinaenglishtour.com

  • torrentleech invite

    8/7/2014 12:12:00 AM |

    I am only commenting to let you know of the remarkable experience our girl encountered reading the blog. She noticed many pieces, which included how it is like to possess an amazing giving nature to get certain people really easily learn certain multifaceted things. You undoubtedly exceeded visitors’ desires. I appreciate you for rendering the important, healthy, informative as well as easy tips about the topic to Kate.

  • DEBORA Laurence

    8/12/2014 1:10:55 PM |

    annuaires-gratuit.com/ vous propose de créer gratuitement un annuaire de sites internet pour un bon référencement.

  • DEBORA Laurence

    8/12/2014 1:19:03 PM |

    annuaires-gratuit.com/ vous propose de créer gratuitement un annuaire de sites internet pour un bon référencement.

  • How to get taller at 16

    8/13/2014 4:47:15 AM |

    Thanks  for another informative site. Where else could I get that kind of information written in such an ideal manner? I've a mission that I'm simply now working on, and I've been on the glance out for such information.

  • DEBORA Laurence

    8/15/2014 2:45:15 AM |

    annuaires-gratuit.com/ vous propose de créer gratuitement un annuaire de sites internet pour un bon référencement.

  • DEBORA Laurence

    8/16/2014 4:23:50 AM |

    annuaires-gratuit.com/ vous propose de créer gratuitement un annuaire de sites internet pour un bon référencement.

  • emr software free

    8/21/2014 6:07:30 AM |

    Hello, Neat post. There is an issue together with your website in web explorer, would check this… IE still is the marketplace chief and a huge part of other folks will omit your excellent writing due to this problem.

  • the dirty computer news

    8/22/2014 1:37:38 AM |

    Hello! Just located Your website On Google Search. Great Site On Your Blog Website!.

  • ketolisis

    8/26/2014 10:14:44 AM |

    Just thought i would comment and say neat ketolisis design, did you code it yourself? Looks great.

  • cryptocurrency prices

    8/31/2014 7:58:51 AM |

    I intended to post you one little note just to thank you so much once again for your personal pretty suggestions you've shown on this site. It is simply extremely open-handed with people like you to convey easily what exactly a few people could possibly have sold as an e book to earn some cash for themselves, precisely considering the fact that you could have done it if you desired. These guidelines also served to be the fantastic way to know that the rest have a similar dream similar to mine to understand way more when it comes to this problem. Certainly there are a lot more pleasurable periods ahead for individuals that scan your website.

  • check my blog

    9/2/2014 2:22:12 AM |

    Hello there, I discovered your blog via Google at the same time as looking for a related matter, your site got here up, it seems to be good. I have bookmarked it in my google bookmarks.

  • Article

    9/12/2014 2:54:31 AM |

    Valuable information. Fortunate me I discovered your website by chance, and I'm shocked why this twist of fate did not took place earlier! I bookmarked it.

  • check over here

    9/12/2014 5:33:57 AM |

    Hello, i think that i saw you visited my blog thus i came to “return the favor”.I'm attempting to find things to enhance my website!I suppose its ok to use some of your ideas!!

  • Cordell Plaisance

    9/15/2014 7:24:02 PM |

    Sorry for the huge review, but I'm really loving the new Zune, and hope this, as well as the excellent reviews some other people have written, will help you decide if it's the right choice for you.

  • DEBORA Laurence

    9/17/2014 12:35:29 PM |

    Covoiturage, annonce & covoiturage. Deposer votre annonce gratuitement sur portail2000.com/ et faites des rencontres

  • DEBORA Laurence

    9/17/2014 1:16:39 PM |

    Covoiturage, annonce & covoiturage. Deposer votre annonce gratuitement sur portail2000.com/ et faites des rencontres

  • additional reading

    9/18/2014 1:16:17 PM |

    I simply want to tell you that I'm newbie to weblog and honestly liked your web site. Likely I’m planning to bookmark your website . You surely have great articles and reviews. Thanks a bunch for revealing your website.

  • Wally Danko

    9/21/2014 9:29:57 AM |

    Thank you, I've been looking for facts about this subject for ages and yours is the best I've located so far.

  • Ethan Bowers

    9/21/2014 10:30:47 AM |

    Good work Smile cheers!

  • Barney Parkos

    9/23/2014 4:26:18 AM |

    This will be a fantastic website, will you be interested in doing an interview about just how you created it? If so e-mail me!

  • Burton Haynes

    9/30/2014 5:03:34 AM |

    Hands down, Apple's app store wins by a mile. It's a huge selection of all sorts of apps vs a rather sad selection of a handful for Zune. Microsoft has plans, especially in the realm of games, but I'm not sure I'd want to bet on the future if this aspect is important to you. The iPod is a much better choice in that case.

  • Interior design

    10/1/2014 4:19:05 PM |

    postsauthors for Interior Design Multimedia Design. Candidates should be Malaysians and have a to join us in the following position: Lecturer Interior Design

  • Trevor

    10/6/2014 12:56:34 AM |

    Hola es la primera ocasión en la que llego a tu blog.

  • Interior design

    10/7/2014 2:56:34 PM |

    Home renovation interior design appartment interior design housing improvement office renovation condominium renovation ubahsuai rumah.

  • http://is.gd/hungergamesmockingjay

    10/8/2014 4:06:01 AM |

    I must show my thanks to the writer for rescuing me from this particular issue. After surfing around through the search engines and coming across proposals that were not productive, I was thinking my entire life was done. Being alive without the presence of strategies to the issues you have sorted out by way of your article content is a serious case, and the kind that might have badly damaged my entire career if I had not noticed your website. Your primary natural talent and kindness in controlling every item was very useful. I don't know what I would've done if I hadn't encountered such a subject like this. I can now relish my future. Thanks for your time very much for the reliable and sensible help. I will not think twice to endorse your blog to anyone who requires counselling on this area.

  • view publisher site

    10/8/2014 10:03:10 PM |

    I just want to mention I'm beginner to blogging and site-building and honestly loved your web site. Probably I’m want to bookmark your blog post . You absolutely have superb stories. Kudos for sharing your blog site.

  • guardians of the galaxy full movie

    10/9/2014 3:56:42 AM |

    I simply wanted to construct a small comment to express gratitude to you for these remarkable techniques you are showing at this website. My time intensive internet look up has finally been paid with reputable concept to talk about with my friends. I 'd express that many of us visitors are undoubtedly endowed to dwell in a wonderful site with so many lovely people with very beneficial solutions. I feel very much blessed to have used the weblog and look forward to really more amazing moments reading here. Thanks a lot once again for a lot of things.

  • guardians of the galaxy full movie online

    10/9/2014 6:01:35 AM |

    Needed to write you a little remark to be able to say thanks yet again with your nice techniques you've featured on this page. This has been really  generous of you to allow unreservedly all that many of us would've offered as an e-book to end up making some dough for their own end, most notably now that you could possibly have done it in case you desired. These tips likewise served as a easy way to realize that many people have a similar zeal like mine to understand a lot more in terms of this matter. I believe there are thousands of more pleasurable situations ahead for individuals that scan through your site.

  • John

    10/9/2014 3:56:50 PM |

    You made some first rate factors there. I looked on the internet for the difficulty and located most people will go along with along with your website.

  • best free microsoft xbox live gold codes

    10/9/2014 6:03:27 PM |

    An interesting dialogue is value comment. I feel that it's best to write more on this matter, it won't be a taboo topic however generally people are not enough to speak on such topics. To the next. Cheers More info at

  • guardians of the galaxy full movie

    10/9/2014 8:56:10 PM |

    I needed to create you the bit of remark so as to thank you very much as before on your pleasant information you've provided in this article. It's certainly extremely open-handed with people like you to provide without restraint all that numerous people might have distributed for an e book in order to make some cash for themselves, and in particular seeing that you could possibly have tried it if you ever wanted. These thoughts likewise worked to provide a easy way to fully grasp that other individuals have the identical fervor similar to my very own to find out a lot more concerning this problem. I know there are a lot more pleasant opportunities up front for individuals that looked at your blog post.

  • minecraft hack

    10/9/2014 11:55:49 PM |

    I wish to show  appreciation to the writer for bailing me out of this setting. Right after surfing around throughout the search engines and coming across strategies which are not helpful, I assumed my entire life was over. Existing without the presence of answers to the difficulties you have resolved by means of this article is a critical case, as well as ones which could have badly affected my entire career if I hadn't come across your blog. Your capability and kindness in maneuvering all areas was vital. I don't know what I would've done if I had not discovered such a stuff like this. I am able to at this time look ahead to my future. Thanks a lot so much for this reliable and amazing guide. I won't think twice to recommend the sites to anybody who should get tips about this subject.

  • Interior design

    10/10/2014 4:24:21 PM |

    Hello all

  • interior

    10/10/2014 4:28:51 PM |

    Today I noticed that our members are posting questions to their question regarding eye disease when they sign up for membership. the place to post these questions is in our INTRODUCTION blog or GENERAL DISCUSSION blog.

  • mario perez-tano

    10/10/2014 11:30:55 PM |

    I  wanted to type a simple message in order to say thanks to you for all the superb pointers you are showing on this site. My extended internet look up has at the end been honored with really good concept to talk about with my colleagues. I 'd repeat that most of us website visitors are unquestionably blessed to live in a perfect website with  many lovely individuals with very beneficial tips and hints. I feel really lucky to have seen the weblog and look forward to some more awesome moments reading here. Thanks a lot once again for a lot of things.

  • app nana codes

    10/16/2014 12:46:37 AM |

    I've observed that in the world the present day, video games are the latest trend with children of all ages. There are occassions when it may be impossible to drag young kids away from the activities. If you want the best of both worlds, there are many educational gaming activities for kids. Thanks for your post.

  • more helpful hints

    10/16/2014 8:20:34 PM |

    Thanks , I have recently been searching for info about this topic for ages and yours is the best I've found out till now. But, what concerning the bottom line? Are you sure about the source?

  • gta 5 money cheat

    10/25/2014 12:37:30 AM |

    I like this website so much, saved to my bookmarks. "American soldiers must be turned into lambs and eating them is tolerated." by Muammar Qaddafi.

Loading

Building Custom Controls for Windows 8 Store apps

Diederik Krols

The XAML Brewer

Building Custom Controls for Windows 8 Store apps

This article explains how to build custom controls for Windows Store apps, using XAML and C#. Custom controls are the most powerful controls in the XAML department. Once you know how to design and build these, you’ll have no problems with their alternatives: user controls, derived controls, and extended controls. Let’s start with a definition: a custom control is a reusable templatable control that comes with a generic.xaml file and some code behind. Generally a custom control is stored in its own assembly to make it reusable in multiple apps. As a developer, you decorate a custom control with properties, methods, events, and a default style. The users of the control –developers who use your custom control in their apps- should live with the code behind, but are free to completely restyle the XAML part.

Hello again, Simple Slider

Almost a year ago, I built a custom slider control in an earlier version of Visual Studio and the Windows Runtime. A lot has changed since then – fortunately for the better. For this article, I decided to redo that slider. I’ll stick to its original anatomy: a horizontal slider is just a draggable Thumb in a Border.  While dragging, a Rectangle is drawn to fill the space at the left side of the Thumb:

Getting Started

Recent versions of Visual Studio 2012 –including the free Express edition- come with a template to create a custom control. All you need to do to get started is adding a new item of the type ‘Templated Control’ to your project:

It will create the code behind file as well as the generic.xaml in the Templates folder.

Properties

A custom control directly inherits from Control itself, the mother of all controls. It immediately comes with a couple of useful properties like Height, Width, and Visibility. Of course you would want to add your own properties. A slider control e.g. should have at least properties to represent its minimum, maximum and current value. Since we’re interested in data binding, we will implement these as DependencyProperty instances. Using the propdp code snippet, you can rapidly define a property and provide its name, type, default value, and the function that will be called when the value changes. In the case of our slider, we are definitely interested in knowing when the value changed: it’s the sign to redraw the control. Here’s how the definition of the Value property looks like:

public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
    "Value", typeof(double), typeof(Slider), new PropertyMetadata(0.0, OnValueChanged));

public double Value
{
    get { return (double)GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }
}

private static void OnValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    // Recalculate part sizes.
    // ...
}

Styling

The generic.xaml file will contain the default style for the control. While typing in that code, you have intellisense but no designer support. Here’s how the basic slider style looks like in XAML.

<Style TargetType="local:Slider">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Slider">
                <Grid>
                    <Border Height="40"
                            VerticalAlignment="Stretch"
                            Background="Gray"
                            Margin="0"
                            Padding="0"
                            BorderThickness="0" />
                    <Canvas Margin="0"
                            Height="40">
                        <Rectangle x:Name="PART_Rectangle"
                                    Height="38"
                                    Fill="SlateBlue"
                                    Margin="0 1" />
                        <Thumb x:Name="PART_Thumb"
                                Background="LightSteelBlue"
                                Width="40"
                                Height="40"
                                Margin="0" />
                    </Canvas>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The default style is assigned to the control in its constructor:

public Slider()
{
    this.DefaultStyleKey = typeof(Slider);
}

This is a screenshot of the custom slider:

In the style definition, the Thumb and Rectangle controls were given an x:Name value. This is because we need to manipulate them when (re)drawing the slider from code behind. That puts some constraints on the ‘templatability’ of the custom control: no matter how the designer wants to make the control look like, he or she needs to make sure that the template contains a Thumb and a Rectangle with the expected name. Fortunately you have some ways to notify these constraints to the designer. First there is a naming convention that specifies that the element’s name should start with ‘PART_’. More important is the fact that you can decorate the class with TemplatePart attributes. These will be recognized by tools like Expression Blend. Here’s the definition in C#:

[TemplatePart(Name = ThumbPartName, Type = typeof(Thumb))]
[TemplatePart(Name = RectanglePartName, Type = typeof(Rectangle))]
public sealed class Slider : Control
{    
    private const string ThumbPartName = "PART_Thumb";
    private const string RectanglePartName = "PART_Rectangle";
        
    // ...
}

You find the named parts with the GetTemplateChild method. When using your control, a designer could have ignored the expected parts, so make sure you look them up defensively: 

protected override void OnApplyTemplate()
{
    this.thumb = this.GetTemplateChild(ThumbPartName) as Thumb;
    if (this.thumb != null)
    {
        this.thumb.DragDelta += this.Thumb_DragDelta;
    }

    // ...

    base.OnApplyTemplate();
}

This code is typically written in an override of the OnApplyTemplate method. Don’t use the Loaded event. The visual tree of a templated control might be still incomplete at that stage.

Visual State Management

Depending on its state (enabled, disabled, focused, snapped, etc.) a control will look and feel slightly or drastically different. This is where the VisualStateManager comes in action. The visual state manager invokes transformations when the state of the control changes. E.g. if the control is disabled, it will recolor it in fifty shades of gray. The states and transformations can be described declaratively in XAML:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
        <VisualState x:Name="Normal">
            <Storyboard>
                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Thumb"
                                                Storyboard.TargetProperty="Background">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="LightSteelBlue" />
                </ObjectAnimationUsingKeyFrames>
                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Rectangle"
                                                Storyboard.TargetProperty="Fill">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="SlateBlue" />
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </VisualState>
        <VisualState x:Name="Disabled">
            <Storyboard>
                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Thumb"
                                                Storyboard.TargetProperty="Background">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="LightGray" />
                </ObjectAnimationUsingKeyFrames>
                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Rectangle"
                                                Storyboard.TargetProperty="Fill">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="DimGray" />
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

When the control is used inside a LayoutAwarePage, then it will listen automagically to state changes. But we can’t make assumptions on how and where our control is going to be used. Fortunately, in code behind it is possible to trigger the visual state manager programmatically. Here’s an example where we disable the control from C#:

private void Slider_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (this.IsEnabled)
    {
        VisualStateManager.GoToState(this, "Normal", true);
    }
    else
    {
        VisualStateManager.GoToState(this, "Disabled", true);
    };
}

Here's the result when the app is running:

Again, this puts some constraints on the templatability of the control: the designer has to make sure that the visual states that we invoke programmatically exist in the overridden style. Again we as developer can document these constraints by decorating the class with TemplateVisualState attributes:

[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
public sealed class Slider : Control
{ 
   // ...
}

Templating

The style in the generic.xaml is just a default style. It can be completely overridden, as long as the TemplatePart and VisualState constraints are respected. Here’s an example of how to give the default slider a brand new jacket:

<cc:Slider>
    <cc:Slider.Template>
        <ControlTemplate TargetType="cc:Slider">
            <Grid>
                <Border Height="80"
                        VerticalAlignment="Stretch"
                        Background="Transparent" />
                <Line VerticalAlignment="Center"
                        X1="0"
                        Y1="0"
                        X2="3000"
                        Y2="0"
                        StrokeThickness="7"
                        Stroke="White"
                        StrokeDashArray="1" />
                <Canvas Margin="0"
                        Height="80">
                    <Rectangle x:Name="PART_Rectangle"
                                Height="12"
                                Canvas.Top="34"
                                Fill="DarkSlateBlue" />
                    <Thumb x:Name="PART_Thumb"
                            Width="80"
                            Height="80">
                        <Thumb.Template>
                            <ControlTemplate>
                                <Image Source="Assets/Pacman.png"
                                        Height="80" />
                            </ControlTemplate>
                        </Thumb.Template>
                    </Thumb>
                </Canvas>
            </Grid>
        </ControlTemplate>
    </cc:Slider.Template>
</cc:Slider>

Here’s how it looks like:

Events

To add an event to your control, just declare it and raise it at the appropriate time. I have decorated the slider with an event ‘BoundHit’ that is raised when the value hits minimum or maximum:

public event EventHandler BoundHit;

private void OnBoundHit(EventArgs e)
{
    if (this.BoundHit != null)
    {
        this.BoundHit(this, e);
    }
}

private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
    // ...
    this.OnBoundHit(EventArgs.Empty);
    // ...
}


The page that hosts the slider can now react to it:

<cc:Slider BoundHit="ccSlider_BoundHit" />

 
This is what it does in the attached sample project:

 

Admit it: you never saw a slider do this ;-)

From Slider to Gauge

This is basically all you need to know to roll your own custom controls. If you don’t believe me, feel free to dive into the attached source code of the following Radial Gauge control. It’s a new version of a control I built some months ago: you find its story here. Since then the .NET framework improved and so did my code. Now the radial gauge may be a bit more complex than the slider: there are some animations and converters involved. But apart from that, it only contains stuff we covered in this article: a default style in generic.xaml, an override of OnApplyTemplate, and a TemplatePart - no visual states. Functionally all that a radial gauge does is rotating a needle when its value changes. That basically makes it a templated … slider. Anyway if you’re looking for a basic radial gauge with a color scale, here you have one:

Alternatives

User Controls

Custom controls are the most powerful controls to build, although not always the most developer-friendly: you don’t have support from Visual Studio’s designer when defining the style. Fortunately this is not the case with User Controls. For more details, check my previous blog item.

Derived Controls

Another alternative is to create a Derived Control, by creating a subclass of an existing control. You can then add properties, methods, and events at will, or override some of its methods. You find examples of derived controls in the Callisto framework. Among other useful controls, that framework  contains the DynamicTextBlock control, a textblock that does trimming at word boundary. It inherits from ContentControl:

public class DynamicTextBlock : ContentControl
{
    // ...
}

Another example of a derived control can be found in the WinRT XAML Toolkit: the WatermarkTextBox inherits from the native TextBox, and adds a watermark.

Extended Controls

Using Attached Properties, you can add extra properties to existing instances, e.g. of controls. This allows you to create new controls without defining control subclasses. Again Callisto as well as WinRt XAML Toolkit have examples of such extensions. You’ll remember the TextBoxValidationExtensions from my blog post on input validation. These extensions allow you to add validation logic to a native textbox:

<TextBox ext:TextBoxValidationExtensions.Format="NonEmptyNumeric"
            ext:TextBoxValidationExtensions.InvalidBrush="Salmon" />

You can take the concept of attached properties one step further to create a Behavior, like the ‘select-all-on-focus’ from another previous blog post:

<TextBox Text="Eh~ Sexy lady. Op op op op oppan Gangnam Style.">
    <WinRtBehaviors:Interaction.Behaviors>
        <local:SelectAllOnFocusBehavior SelectAllOnFocus="True" />
    </WinRtBehaviors:Interaction.Behaviors>
</TextBox>

The attached solution contains the source code for all mentioned alternative controls. Here’s how the corresponding sample page looks like:

Code Code Code

Here’s the full source code of all the featured controls in this article (o, and a free forward-button style). It was written in Visual Studio 2012 Ultimate, without SP1: U2UConsult.CustomControls.Sample.zip (256.78 kb).

Enjoy!

Diederik

Comments (9) -

  • Nathan

    8/2/2013 6:10:31 AM |

    Your example code doesn't initialize the visual state for IsEnabled correctly.  Instead of having Slider_IsEnabledChanged(this, null) in the constructor, it needs to be in the OnApplyTemplate() override otherwise the VisualState doesn't exist yet and the styles don't get applied.

    Check the returned value from VisualStateManager.GoToState to verify.

  • Jesse

    8/7/2013 11:05:13 AM |

    Nice write up, thanks!
    Any idea how you could use this custom control in a javascript Windows Store app?

  • Custom Boxes Printing

    10/16/2013 1:14:39 PM |

    I always spent my half an hour to read this blog's articles every day along with a cup of coffee.|

  • Kevin

    10/24/2013 10:37:50 PM |

    I am trying to port your awesome gauge back to WPF. Since there lacks a community guide on how to port app from
    WPF to windows store app, it makes it quite difficulty for who is new to both worlds. So far I have replaced all "using" with "clr/namespace", Windows.UI.* with System.Windows.*, and also the static constructors.
    Still I got these erros:
    1. OnValueChanged(this, null): cannot convert from null to System.Windows.DependencyPropertyChangedEventArgs
    2. The name "Gauge" does not exist in the namespace "clr/namespace:U2UConsult.WinRT.Modern.Controls"
    3.And Windows.Foundation.Metadata.WebHostHidden give errors too.
    Since you have expertise in both technologies, it would be nice if you would make a tutorial on the migration from WPF to Window store app.

  • Janey Irish

    12/3/2013 10:04:26 PM |

    It’s the little changes that make the most important changes. Thanks for sharing!|

  • activate

    1/28/2014 5:11:26 AM |

    Hello Thank You For Making The Very Entertaining Weblog Post Keep Up The Good Work!! I Posted A Backlink To My Activate Windows Guide To Show You How To Activate Windows 7 Ultimate 64 Bit! Enjoy!

  • Elinore Hatler

    2/7/2014 2:09:28 AM |

    Made to measure curtains… check out the sites listed below, worth a read for interiors and rugs enthusiasts…

  • Lashawna Mullick

    2/15/2014 3:01:10 AM |

    Wonderful work! That is the type of info that are meant to be shared across the net. Disgrace on the search engines for not positioning this submit higher! Come on over and consult with my site . Thank you =)

Comments are closed