Tuesday, November 9, 2010

Silverlight FluidMoveBehavior


Recently, I discovered something convenient that Silverlight has to offer by default. Well, actually, it’s Blend who’s offering it in it’s Microsoft.Expression.Interactions assembly. It’s the FluidMoveBehavior!
What this basically does is animating a change in the position of an element. One of the most clear examples for this is within a WrapPanel. The code is just as easy as the following:

<ListBox>           
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <Toolkit:WrapPanel Orientation="Horizontal">
                <Interactivity:Interaction.Behaviors>
                    <Interactions:FluidMoveBehavior AppliesTo="Children" Duration="00:00:00.250">
                        <Interactions:FluidMoveBehavior.EaseX>
                            <PowerEase EasingMode="EaseIn" Power="5"/>
                         </Interactions:FluidMoveBehavior.EaseX>
                     </Interactions:FluidMoveBehavior>
                 </Interactivity:Interaction.Behaviors>
            </Toolkit:WrapPanel>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

Voila! That’s it. Now all actions on the children in the ListBox are animated, so when you remove one, all the items that follow will move fluently into the free space. And when changing the size , all the items slide nicely to their new position. I suggest that you never let the duration be too long, but a little animation can make your application just a bit sexier. And as you can see, you don’t need to do a lot of effort for it.

And there is even more! When you use the FluidMoveSetTagBehavior, you can animate a transition on an element from a starting point, to somewhere outside your starting location. You can find a good explanation and example at MSDN.

Hopefully this little tip helps you make your applications a bit more fluid! I certainly found it very useful.

Saturday, May 29, 2010

Removing the use of IADsLargeInteger when reading from Active Directory using DirectorySearcher


And now, for something completely different! Recently, I needed to do account managing in an application, and the users were stored in Active Directory. A very useful site for lot’s of operations in AD is this one.
But I encountered a problem with some properties, like “pwdLastSet”. This property can only be set to zero, and it can be useful to force the user to change his password. For instance when his account is created with a random generated password. When the user tries to log in, it will fail, and you can supply him with a screen to change his password. But reading the “pwdLastSet” property proved to be a little bit more difficult than expected, because it is a large integer, which is rather hard to read from Active Directory.

At first, I found this site which got the job done using a IADsLargeInteger, which uses COM Interop to read the value. The code looked something like this:

System.Int64 largeInt = 0;
IADsLargeInteger int64Val = (IADsLargeInteger)userEntry.Properties["pwdLastSet"].Value;
largeInt = int64Val.HighPart * 0x100000000 + int64Val.LowPart;
bool isPwdSet = largeInt == 0;

However the code is not that big, you need a reference to the ActiveDS library and I thought it could be nice if I didn’t need that one. So when I looked a bit further, I found out that the DirectorySearcher also can convert a large integer to an Int64. To make life a little bit easier I wrote an extension method on a DirectoryEntry, to get an Int64 from a given property. The code is the following:

public static Int64 GetInt64(this DirectoryEntry directoryEntry, string propertyName)
{
    DirectorySearcher ds = new DirectorySearcher(directoryEntry, String.Format("({0}=*)", propertyName), new[] { propertyName }, SearchScope.Base);
    SearchResult sr = ds.FindOne();

    if (sr != null)
    {
        if (sr.Properties.Contains(propertyName))
        {
            return (Int64)sr.Properties[propertyName][0];
        }
    }
    return -1;
}

This way, you can get any large integer from a DirectoryEntry object in a nice clean way, without any nasty COM Interop!

Saturday, January 16, 2010

Silverlight 3 Commanding : other uses

Commanding with Prism in Silverlight is usually done together with MVVM, and I assume most people have at least heard of MVVM. The most common use is the Click command on buttons, but we can also use commanding for other purposes, which I’m now going to demonstrate.

It’s not uncommon for business applications to have different kinds of users, certain users are admins, certain only have read-only rights, … The biggest problem is when all users are allowed to acces the same page, but cannot execute the same actions on that page.  To solve this, we can use our own commanding to disable, hide, or make elements readonly on pages.

This implementation is based on Prism, and we just change it to our own needs. But let's begin. To keep it simple, I’ll first just create 2 enums which contains the actions and rights. You’ll probably take a different approach in a large application, but this is just for demonstrating purposes.
public enum UserRights
    {
        CanSeeName, CanSeeAddress, CanSeeEmail, CanSeeTelephone, CanSave, CanDelete
    }

public enum ElementAction
    {
        Disable, Hide, ReadOnly
    }
Now, we create our base behavior that will allow us to use it in our XAML to attach to an element.


public class RightsBehaviorBase<T> where T : FrameworkElement
    {
        private UserRights _userRights;
        private ElementAction _elementsAction;
        private readonly WeakReference _targetObject;

        public UserRights UserRights
        {
            get { return _userRights; }
            set { _userRights = value; }
        }

        public ElementAction ElementsAction
        {
            get { return _elementsAction; }
            set { _elementsAction = value; }
        }

        protected T TargetObject
        {
            get { return _targetObject.Target as T; }
        }

        public RightsBehaviorBase(T targetObject)
        {
            _targetObject = new WeakReference(targetObject);
        }

        protected virtual void ExecuteCommand()
        {
            // If the user has no right, apply the correct action
            if (!RightsManager.HasUserRight(_userRights))
            {
                switch (_elementsAction)
                {
                        //When action is disable, always make sure IsEnabled is false.
                    case ElementAction.Disable:
                        //Since the property IsEnabled can only be applied to members from the Control namespace, we have to check for this
                        if (TargetObject is Control)
                        {
                            var control = (Control)((FrameworkElement)TargetObject);
                            control.IsEnabled = false;
                            control.IsEnabledChanged += (sender, e) =>
                            {
                                if (((Control)sender).IsEnabled != false)
                                    ((Control)sender).IsEnabled = false;
                            };
                        }
                        else
                        {
                            throw new ArgumentException("Target object is not a member of the Control namespace.");
                        }
                        break;
                    //When action is Hide, never make the element visible.
                    case ElementAction.Hide:
                        TargetObject.Visibility = Visibility.Collapsed;
                        TargetObject.LayoutUpdated += (s, e) =>
                        {
                            if (TargetObject.Visibility == Visibility.Visible)
                                TargetObject.Visibility = Visibility.Collapsed;
                        };
                        break;
                    //When action is ReadOnly, make sure element is always ReadOnly. Because the property IsReadOnly can be 
                    //applied to different elements (like TextBox or DataGrid), reflection is used to acces the property.
                    case ElementAction.ReadOnly:
                        var type = TargetObject.GetType();
                        var prop = type.GetProperty("IsReadOnly");
                        if (prop != null)
                        {
                            prop.SetValue(TargetObject, true, null);
                            TargetObject.LayoutUpdated += (s, e) =>
                            {
                                if (!(bool)prop.GetValue(TargetObject, null))
                                    prop.SetValue(TargetObject, true, null);
                            };
                        }
                        else
                            throw new ArgumentException(string.Format("{0} has no property IsReadOnly.", TargetObject.GetType()));
                        break;
                }
            }
        }
    }
This class contains the method that will actually execute the logic to decide which action should be taken on the element the behavior is set. Note that it reacts to changes made by the developer so he can be sure the element will always be in the state it should be. This is convenient in the way that the developer doesn’t have to care about it at all while creating an application. He can change the property in the UI but it will never change. So if it’s set to disabled, it will always be like that.

The next step is creating the behavior, that will trigger the ExecuteCommand on an event triggered by the element in the UI. This behavior is needed, because Silverlight 3 does not has commanding support.
Here we want that the right we set is applied when the FrameworkElement is loaded, but remember, you can hook it up to any event here, if you need it.
public class RightsBehavior : RightsBehaviorBase<FrameworkElement>
    {
        public RightsBehavior(FrameworkElement objectToSet)
            : base(objectToSet)
        {
            objectToSet.Loaded += (sender, e) => ExecuteCommand();
        }
    }
The third and last class we need to add is a static class that holds all the Dependency properties that will allow us to use the behavior in our XAML code.


public class RightsCommand
    {
        private static readonly DependencyProperty RightsBehaviorProperty = DependencyProperty.RegisterAttached(
           "UmRightsManagementBehavior",
           typeof(RightsBehavior),
           typeof(RightsCommand),
           null);

        public static readonly DependencyProperty UserRightsProperty = DependencyProperty.RegisterAttached(
            "UserRight",
            typeof(UserRights),
            typeof(RightsCommand),
            new PropertyMetadata(OnSetCommandCallback));

        public static readonly DependencyProperty ElementActionProperty = DependencyProperty.RegisterAttached(
            "ElementAction",
            typeof(ElementAction),
            typeof(RightsCommand),
            new PropertyMetadata(OnSetCommandParameterCallback));

        public static void SetUserRight(FrameworkElement fwe, UserRights userRight)
        {
            fwe.SetValue(UserRightsProperty, userRight);
        }

        public static UserRights GetUserRight(FrameworkElement fwe)
        {
            return (UserRights)fwe.GetValue(UserRightsProperty);
        }

        public static void SetElementAction(FrameworkElement fwe, ElementAction parameter)
        {
            fwe.SetValue(ElementActionProperty, parameter);
        }

        public static ElementAction GetElementAction(FrameworkElement fwe)
        {
            return (ElementAction)fwe.GetValue(ElementActionProperty);
        }

        private static void OnSetCommandCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement fwe = dependencyObject as FrameworkElement;
            if (fwe == null) return;

            var behavior = GetOrCreateBehavior(fwe);
            behavior.UserRights = (UserRights)e.NewValue;            
        }

        private static void OnSetCommandParameterCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            var fwe = dependencyObject as FrameworkElement;
            if (fwe == null) return;

            var behavior = GetOrCreateBehavior(fwe);
            behavior.ElementsAction = (ElementAction)e.NewValue;
        }

        private static RightsBehavior GetOrCreateBehavior(FrameworkElement fwe)
        {
            RightsBehavior behavior = fwe.GetValue(RightsBehaviorProperty) as RightsBehavior;
            if (behavior == null)
            {
                behavior = new RightsBehavior(fwe);
                fwe.SetValue(RightsBehaviorProperty, behavior);
            }
            return behavior;
        }
    }
Now you can reference the commanding classes and use it like this
 <TextBox Commands:RightsCommand.UserRight="CanSeeName" Commands:RightsCommand.ElementAction="ReadOnly" />
When the user has the right ‘CanSeeName’, the TextBox will be editable, but when the user doesn’t, it will be ReadOnly.

This concludes this post. But as I said, this is just one small example of taking a different approach on commanding. There are much more things where it can be useful. I hope this post helps people understand it and makes the commanding more understandable so you can use it!

I’ve also uploaded the full source code with a little example.

Thursday, December 3, 2009

Silverlight 3 and WCF Faults

Recently, I encountered something convenient which I thought was worth sharing. Everyone working with WCF and Silverlight may have been troubled by the fact that Faults that were throw by WCF don’t get to the Silverlight client properly. You would always get a CommunicationException, with no details of what actually went wrong on the backend.
After searching, I found a useful solution where there was some sort of SilverlightFaultBehavior, a custom endpoint behavior, that changed the HTTP status code from 500 (server error) to 200 (OK). This way Silverlight can read the Fault and get some useful information.

But Silverlight 3, there is no need for that anymore!
Apperently, Silverlight uses the browser’s HTTP stack by default, which is limited to GET and POST commands. This is the reason why SOAP faults couldn’t be propagated to the client. Now in Silverlight 3, you can subscribe your client to bypass the browser’s HTTP stack and let Silverlight handle it.

Simply do this by using the following code somewhere at the startup of your Silverlight application.

bool httpResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
bool httpsResult = WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);

If the httpResult is true, which is should be, you will receive all faults you send without having to do any additional coding.

Wednesday, November 18, 2009

Some useful extension methods

While developping you often find that there are some things that really are lacking in some classes. Here are some of my extension methods. Some of them are more useful than others.

The file includes the following extension methods:

public static class Extensions
{
public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> source)
{
var observableCollection = new ObservableCollection<T>();
foreach (var t in source)
{
observableCollection.Add(t);
}
return observableCollection;
}



public static void AddRange<T>(this ObservableCollection<T> source, IEnumerable<T> items)
{
foreach (var item in items)
{
source.Add(item);
}
}



public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
if (action == null) throw new ArgumentNullException();

foreach (var item in source)
{
action(item);
}
}



public static void ForEachWithIndex<T>(this IEnumerable<T> source, Action<T, int> action)
{
if (action == null) throw new ArgumentNullException();

int index = 0;
foreach (T item in source)
{
action(item, index++);
}
}



public static bool ItemsEqual<T>(this IEnumerable<T> left, IEnumerable<T> right)
{
IEnumerator leftEnumerator = left.GetEnumerator();
IEnumerator rightEnumerator = right.GetEnumerator();

while (leftEnumerator.MoveNext() && rightEnumerator.MoveNext())
{
if (leftEnumerator.Current != rightEnumerator.Current)
{
return false;
}
}
return true;
}



public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
Random rnd = new Random();
return source.Select(t => new { Index = rnd.Next(), value = t }).OrderBy(x => x.Index).Select(x => x.value);
}



public static T Clone<T>(this T source)
{
T cloned = (T)Activator.CreateInstance(source.GetType());
foreach (PropertyInfo curPropInfo in source.GetType().GetProperties())
{
if (curPropInfo.GetGetMethod() != null
&& (curPropInfo.GetSetMethod() != null))
{
if (curPropInfo.Name != "Item")
{
object getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] { });

if (getValue != null && getValue is DependencyObject)
getValue = Clone((DependencyObject)getValue);

curPropInfo.GetSetMethod().Invoke(cloned, new[] { getValue });
}
else
{
int numberofItemInColleciton =
(int) curPropInfo.ReflectedType.GetProperty("Count").GetGetMethod().Invoke(source, new object[] { });

for (int i = 0; i < numberofItemInColleciton; i++)
{
object getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] { i });

if (getValue != null && getValue is DependencyObject)
getValue = Clone((DependencyObject)getValue);

curPropInfo.ReflectedType.GetMethod("Add").Invoke(cloned, new[] { getValue });
}
}
}
}
return cloned;
}

#region VisualTree Extensions

public static IEnumerable<DependencyObject> GetChildren(this DependencyObject depObject)
{
int count = depObject.GetChildrenCount();
for (int i = 0; i < count; i++)
{
yield return VisualTreeHelper.GetChild(depObject, i);
}
}



public static DependencyObject GetChild(this DependencyObject depObject, int childIndex)
{
return VisualTreeHelper.GetChild(depObject, childIndex);
}



public static DependencyObject GetChild(this DependencyObject depObject, string name)
{
var children = depObject.GetChildren();
foreach (var child in children)
{
var element = child as FrameworkElement;
if (element != null)
{
if (element.Name == name)
return element;
var innerElement = element.FindName(name) as DependencyObject;
if (innerElement != null)
return innerElement;
}
var innerChild = child.GetChild(name);
if (innerChild != null)
return innerChild;
}
return null;
}



public static int GetChildrenCount(this DependencyObject depObject)
{
return VisualTreeHelper.GetChildrenCount(depObject);
}



public static DependencyObject GetParent(this DependencyObject depObject)
{
return VisualTreeHelper.GetParent(depObject);
}

#endregion
}


Download full file.

The most useful extensions are ToObservableCollection, AddRange to an ObservableCollection (big miss I personally find), a ForEachWithIndex, which I find useful multiple times. This changes something like this:

 var i = 0;
 foreach (var item in list)
 {
    Console.WriteLine("{0}: {1}", i++, item);
 }

To something like this:

list.ForEachWithIndex((item, i) => Console.WriteLine("{0}: {1}", i, item));

There is also a Shuffle method, which randomizes the items in a collection, a Clone method, for when you really need a copy of something that’s not by reference. And there are also some VisualTree extensions, of which the most useful is probably the recursive GetChild() method, which goes down the tree of a DependencyObject to get the object that you need.

The full file with comments can be found here.

Don’t forget to share your extension methods when you have something good!