Archive for March, 2009

How to Create a Custom Dependency Property

Hello Everyone!

Today I’m going to talk about how to create a Custom Dependency Property for use within WPF.  When used with creating custom controls they can be used to extend the functionality of the control.  They can be used for many other reasons but for now we are going to stick within the context of using them for a control.

Lets say were going to build a sort of Watermark text functionality into a TextBox control.  This will allow a developer to specify a string of light gray text that should be shown when no text is present and the control doesnt have any form of focus.  Well the first thing we will need is a custom property on the TextBox control to store this text in.  This is the perfect place to use a DependencyProperty.

First lets create our class.

public class WatermarkedTextBox : TextBox
{
    static WatermarkedTextBox()
    {

        DefaultStyleKeyProperty.OverrideMetadata(typeof(WatermarkedTextBox),
new FrameworkPropertyMetadata(typeof(WatermarkedTextBox)));
    }
}

Next were going to use yet another wonder snippet provided by Visual Studio called propdp.

If we type in propdp and hit tab twice we will see this appear.

public int MyProperty
{
    get { return (int)GetValue(MyPropertyProperty); }
    set { SetValue(MyPropertyProperty, value); }
}

public static readonly DependencyProperty MyPropertyProperty =
    DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new UIPropertyMetadata(0));

This should be very familiar from my previous blog on WPF Attached Properties.  We are going to tab through and the the property type to string, the property name to WatermarkText, the ownerclass to WatermarkedTextBox, and the default value to string.empty.

Our property should now look like so

public string WatermarkText
{
    get { return (string)GetValue(WatermarkTextProperty); }
    set { SetValue(WatermarkTextProperty, value); }
}

public static readonly DependencyProperty WatermarkTextProperty =

    DependencyProperty.Register("WatermarkText", typeof(string), typeof(WatermarkedTextBox),
new UIPropertyMetadata(string.Empty));

And that is it!  We now have ourselves a custom dependency property that we can use to store the text intended for the watermark functionality.  Now we can use things like TemplateBinding inside of our templates for this control to bind an elements Text or Content property to this.  This could be a label, maybe an adorner, there are many ways this can be used.  And because its a DependencyProperty we can take full advantage of what WPF provides like the Binding system, setting from Styles and if the return type were one that is animateable like double then we could also animate it.

There are a few things to note about creating a DependencyProperty.  Sometimes people like to put logic into property setters for functionality when that property has changed.  When we use a DependencyProperty the setter of the actual property that wraps the call to SetValue, does not always get called.  If something changes the property in the dependency system behind the scenes then your code is never run.

Luckilly we have a nice solution for this!  There are two different ways we can still provide this functionality.

The first way we can do this is by applying a delegate to be a PropertyChanged handler for the dependency property.  We have another constructor parameter in the UIPropertyMetadata object that will accept this delegate.  When we apply it, it should appear as shown.

public string WatermarkText
{
    get { return (string)GetValue(WatermarkTextProperty); }
    set { SetValue(WatermarkTextProperty, value); }
}

public static readonly DependencyProperty WatermarkTextProperty =

    DependencyProperty.Register("WatermarkText", typeof(string), typeof(WatermarkedTextBox),

                                 new UIPropertyMetadata(string.Empty, OnWatermarkTextChanged));



public static void OnWatermarkTextChanged(DependencyObject box, DependencyPropertyChangedEventArgs e)
{
     //Add changed functionality here
}

The second way to do this is by overriding OnPropertyChanged.  Any class that inherits from DependencyObject will automatically have this override available to them.  This method accepts DependencyPropertyChangedEventArgs e that will provide us the property that has changed, the new value, and the old value.  This is one way we might implement this.

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
    base.OnPropertyChanged(e);

    if (e.Property == WatermarkedTextBox.WatermarkTextProperty)
    {
        //add changed functionality here
    }
}

There are many other things we can do with a DependencyProperty and to get more information please check out the MSDN page on How to: Implement a Dependency Property.

I hope this article helps and have a good day!

No Comments

What would YOU like read about!

Good Morning Everyone!

So i have started my WPF blog and have a post on Attached Properties while also providing the beginnings of a Field-Level security mechanism.  I have many many other ideas for WPF topics I want to post about, but I also want to hear what YOU, the most important person to me, wants to read about!

Send me an email at jasonr@magenic.com or post a comment on this post to submit an idea for a WPF topics and i will see if I can choose a few and start building something for them.

And as always!! Happy Coding :)

No Comments

WPF Attached Properties with Field Level Security Example

Hello Everyone!

So today I’m going to be showing you how to use WPF Attached Properties and show how we can make the beginnings of providing Field-Level security features that can be set on any provided or custom WPF control.

So: What is an Attached Property?.  An Attached Property is a property that makes use of the Dependency system to “attach” a property and a value to an instance of a DependencyObject.  What this means is that the object itself does not have the property compiled into itself, but instead the dependency system will store the object and the related attached property value.  So when you go to retrieve or set the value of the Attached Property you will pass in the instance of the object you want to set or retrieve from and it will check the dependency system if this instance has a value (when retrieving) or it will register the value, object, and property name into the dependency system.  This allows us to assign values to properties that do not actually exist on the DependencyObject.

So let’s now create our first Attached Property and see how we can use it to create the beginnings of a Field-Level security mechanism!

First create a class called ApplicationSecurity.  This class can be static or instance, but must be public if intended to be used from the outside.

Luckily Visual Studio 2008 (I have not tried in previous versions of Visual Studio) already has a snippet for us to simply create the shell of the an Attached Property.  This snippet is called propa.  So if we type propa then tab twice it will create the code you will se below.

public static int GetMyProperty(DependencyObject obj)
{
       return (int)obj.GetValue(MyPropertyProperty);
}

public static void SetMyProperty(DependencyObject obj, int value)
{
       obj.SetValue(MyPropertyProperty, value);
}


public static readonly DependencyProperty MyPropertyProperty =

      DependencyProperty.RegisterAttached("MyProperty", typeof(int), typeof(ownerclass),
new UIPropertyMetadata(0));

There are 4 green placeholders for modifying the default information of the snippet to really create our Attached Property.  The first placeholder will what Type you expect the Dependency property to be.  Since we are working towards Field-Level security we are going to go ahead and make it of type string.  So type string into the first area then hit tab.  You will see it also modifies other parts of the snippet in order to propogate the correct type that it needs. 

The second green placeholder is the name of our property.  When thinking of providing field level security we might want to go about a way of defining a unique field context name for our field.  So if you image you have a screen control called PersonView and it contains a FirstName field you might want to assign that field PersonViewFirstName to provide a unique identifier for this field.  So for this part of the snippet we will type in FieldContextName and hit tab.  Again you will see that it will modify other parts of the snippet in order to maintain what it needs.

The third green placeholder is the owner type.  This will generally be the type of class you put the property in.  So since we are in a class called ApplicationSecurity we would type in ApplicationSecurity.  The placeholder is already in the typeof declaration so no need to include that.

The fourth green placeholder is the default value contained inside the UIPropertyMetadata parameter.  If your property return type is a reference type (object) then you must set this to null.  If you set this to a new instance of the object that same instance will be the default for all references to the property across all objects.  This can get messy so we will just set it to null.  If its a value type you can set it to the intended default.  Since we are making a string property we will type in string.Empty and hit enter. 

This ends the creation of our snippet and our Attached Property and here is what you end up with.

public static string GetFieldContextName(DependencyObject obj)
{
    return (string)obj.GetValue(FieldContextNameProperty);
}

public static void SetFieldContextName(DependencyObject obj, string value)
{
    obj.SetValue(FieldContextNameProperty, value);
}

public static readonly DependencyProperty FieldContextNameProperty =

         DependencyProperty.RegisterAttached("FieldContextName", typeof(string),

                typeof(ApplicationSecurity), new UIPropertyMetadata(string.Empty));



We now have an Attached Property called FieldContextName that we can use to assign a value to any DependencyObject with this property name.  This is how you would use it in XAML.

<TextBox appSec:ApplicationSecurity.FieldContextName="PersonViewFirstName" />

When this instance of the TextBox is created it will automatically register this property with this TextBox and the value into the Dependency System.  If you wanted to manually manually work with this from code-behind (which is mostly the same as what happens automatically when done from XAML) this is how you would do this.

TextBox myTextBox = new TextBox();
ApplicationSecurity.SetFieldContextName(myTextBox, "PersonViewFirstName");

string fieldContextName = ApplicationSecurity.GetFieldContextName(myTextBox);

So that is the basics of how to use Attached Properties.  But now lets look at how we can slightly extend this functionality so that when the control is created (or the property is set from code behind) it will evaluate what its security level should be.

In the UIPropertyMetadata object added as a parameter to the registration of the Attached Property we have a few more overloaded parameters that we can add.  The second parameter (after setting the default value) accepts a PropertyChangedCallback object whose constructor accepts a static delegate that is called when the value changes. You can also just put the delegate directly as the parameter instead of creating the PropertyChangedCallback object.  Here is how our property looks now.

public static string GetFieldContextName(DependencyObject obj)
{
    return (string)obj.GetValue(FieldContextNameProperty);
}

public static void SetFieldContextName(DependencyObject obj, string value)
{
    obj.SetValue(FieldContextNameProperty, value);
}

public static readonly DependencyProperty FieldContextNameProperty =

   DependencyProperty.RegisterAttached("FieldContextName", typeof(string), typeof(ApplicationSecurity),
new UIPropertyMetadata(string.Empty, OnFieldContextNameChanged));

So now lets take a look at that method.

private static void OnFieldContextNameChanged(DependencyObject, obj, DependencyPropertyChangedEventArgs e)
{
     //ApplicationSecurityManager.EvaluateField(obj, e.NewValue);
}

So what will happen now is anytime the FieldContextName is set onto a Dependency object whether through XAML or code-behind this method will be called.  The obj parameter is the DependencyObject that this property was set on, and the e parameter will contain OldValue and NewValue.  So you see that if we use this on a WPF control at this point we could pass the context that this field belongs to, to evaluate what needs to happen to the control, and since you have the control also its already available so that you can make any modifications based on security (ie.  Set Visibility to Collapsed because the current user doesnt have access to this field).

I hope people enjoy this comment and please feel free to leave comments, suggestions, criticisms.

1 Comment

My First Blog

Hello Everyone!

My name is Jason Rainwater and i am a Consultant for Magenic Technologies.  Friends and colleagues have been suggesting I start a blog to share with everyone the knowledge of Microsoft’s WPF Framework, so here I am!

I hope to be covering many aspects, concepts, usage and practices for WPF and hope most of that people benefit from what I know.  I will never admit to knowing everything about WPF and always welcome suggestions and comments on topics I write about.

I hope you all will enjoy what I have to share and stay tuned for the real content to come!

No Comments