Posted by: Zeeshan Amjad | September 14, 2009

Making read only Dependency Property


If we want to make a normal CLR property then it is very simple. We either don’t make a setter function of it or make it private. In case of shortcut provided by C# 3.0 we can use the private keyword with the set. Here is one simple class of employee with one read only property Company.

  1: public class Employee
  2: {
  3:     public String Name
  4:     { get; set; }
  5: 
  6:     public String Company
  7:     { get; private set; }
  8: }
  9: 

If we want to set the Company property then it will give the compilation error.

  1: Employee emp = new Employee();
  2: 
  3: emp.Name = "Bob Smith";
  4: emp.Company = "My Company";
  5: 

But the situation is not very simple in case of dependency property. Here is our first attempt to make dependency property as a read only property.

  1: public class Employee : DependencyObject
  2: {
  3:     public static readonly DependencyProperty NameProperty =
  4:         DependencyProperty.Register("Name", typeof(string), typeof(Employee));
  5: 
  6:     public string Name
  7:     {
  8:         get { return (string)GetValue(NameProperty); }
  9:         set { SetValue(NameProperty, value); }
 10:     }
 11: 
 12:     public static readonly DependencyProperty CompanyProperty =
 13:         DependencyProperty.Register("Company", typeof(string), typeof(Employee),
 14:         new PropertyMetadata("WPF In Corp"));
 15: 
 16:     public string Company
 17:     {
 18:         get { return (string)GetValue(CompanyProperty); }
 19:         private set { SetValue(CompanyProperty, value); }
 20:     }
 21: 
 22: }
 23: 

This is quite good start and in fact this one also have a default value of company. If we try to set the dependency property then we will get the compilation error.

  1: Employee emp = new Employee();
  2: 
  3: emp.Name = "Bob Smith";
  4: emp.Company = "My Company";
  5: 

But the problem is when we are using this class in XAML. We have already seen that when working in XAML then it directly calls the SetValue, GetValue function not the .Net properties wrapper.

Making dependency property read only is a multi step process. We have to create an static read only object of DependencyPropertyKey class. This class is inherited by Object. It has only one method and one property.  Here is its class diagram.

 

DependencyProperty 

In first step we are going to make an object of DependencyPropertyKey. Then we create object of DependencyProperty object using the property of dependency property key class. Here is a code to make the Company as a read only dependency property with default value.

  1: public class Employee : DependencyObject
  2: {
  3:     public static readonly DependencyProperty NameProperty =
  4:         DependencyProperty.Register("Name", typeof(string), typeof(Employee));
  5: 
  6:     public string Name
  7:     {
  8:         get { return (string)GetValue(NameProperty); }
  9:         set { SetValue(NameProperty, value); }
 10:     }
 11: 
 12:     private static readonly DependencyPropertyKey CompanyPropertyKey =
 13:         DependencyProperty.RegisterReadOnly("Company", typeof(string), typeof(Employee),
 14:         new PropertyMetadata("WPF In Corp"));
 15: 
 16:     private static readonly DependencyProperty CompanyProperty = 
 17:         CompanyPropertyKey.DependencyProperty;
 18: 
 19:     public string Company
 20:     {
 21:         get { return (string)GetValue(CompanyProperty); }
 22:         private set { SetValue(CompanyProperty, value); }
 23:     }
 24: }
 25: 

Now if we want to set the Company name then we will get compilation error. Here is the complete C# program to demonstrate the read only dependency property.

  1: using System;
  2: using System.Windows;
  3: 
  4: public class Employee : DependencyObject
  5: {
  6:     public static readonly DependencyProperty NameProperty =
  7:         DependencyProperty.Register("Name", typeof(string), typeof(Employee));
  8: 
  9:     public string Name
 10:     {
 11:         get { return (string)GetValue(NameProperty); }
 12:         set { SetValue(NameProperty, value); }
 13:     }
 14: 
 15:     private static readonly DependencyPropertyKey CompanyPropertyKey =
 16:         DependencyProperty.RegisterReadOnly("Company", typeof(string), typeof(Employee),
 17:         new PropertyMetadata("WPF In Corp"));
 18: 
 19:     private static readonly DependencyProperty CompanyProperty = 
 20:         CompanyPropertyKey.DependencyProperty;
 21: 
 22:     public string Company
 23:     {
 24:         get { return (string)GetValue(CompanyProperty); }
 25:         private set { SetValue(CompanyProperty, value); }
 26:     }
 27: }
 28: 
 29: public class ReadOnlyDPSample
 30: {
 31:     [STAThread]
 32:     public static void Main()
 33:     {
 34:         Window win = new Window();
 35:         win.Title = "Readonly Dependency Property";
 36:         win.Width = 400;
 37:         win.Height = 300;
 38: 
 39:         Employee emp = new Employee();
 40: 
 41:         emp.Name = "Bob Smith";
 42: 
 43:         String text = String.Format("Name = {0}\nCompany = {1}",
 44:             emp.Name, emp.Company);
 45: 
 46:         win.Content = text;
 47: 
 48:         Application app = new Application();
 49:         app.Run(win);
 50: 
 51:     }
 52: }
 53: 

Here is the output of this program.

ReadOnlyDependencyProperty

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: