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. #1 by Venkat on December 31, 2009 - 2:19 am

    Hi,

    I want to implement control level security in my WPF application. In my WPF application I will be having set of forms, depends on login user role i should enable/disable some controls. Could you please give me some idea, how can i proceed on this?

    Thanks in advance.

Comments are closed.