Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Countdown to Silverlight 3 #1: Out of Browser applications

With Silverlight 3 knocking on the door (July 10?) it’s time to offload my Silverlight 3 examples. Not that they would show anything new (since SL3 Beta got out, new features had been demoed by various people to the death), it’s just another perspective or a way to go public with a sample code that’s been piling up on my desktop since the Beta was released. Anyway, this will be in a form of short posts with provided test page and sample code.

I’ll begin with probably the most talked about new feature – Out of Browser applications, which could also be referred to as installed applications.

First of – not every Silverlight application can be installed on the client machine. The developer must enable this by adding a <Deployment.Application> section to the application manifest (AppManifest.xml). This section provides more information about the application (name, title, description), along with optional icons in a few different sizes, which are used for branding your application and are displayed on various places on the desktop (install dialog, application shortcut, title bar, …)

Alternative way to installing the application (a common way is to install it through the Silverlight application right-click context menu) is to provide the user with a button of some sort, which would call the new Application.Current.Detach() method when clicked. Note that the method requires an explicit user action to succeed; calling it on the application load or perhaps inside a timer tick event should fail with the exception.

There’s the Application.Current.ExecutionState property telling the installation state of the application. Possible values include RunningOnline (not installed, the default), Detaching, Detached, DetachedUpdatesAvailable and DetachFailed (for describing various installed/ing states).

When installed, the application can be run as before, inside the browser, or, by calling it through a created shortcut (start menu, desktop), outside the browser. Inspecting the Application.Current.RunningOffline property will tell you how the application was run.

To check if application is connected to the network, there’s the NetworkInterface.GetIsNetworkAvailable() method, returning a simple true or false. Remember that being connected to the network doesn’t mean application has access to the internet, and certainly doesn’t imply that a network resource or a service application wants to call is accessible at all.

One last thing to mention is that Out of Browser application still run in a partial trust, the same security context as it would when run inside the browser. The isolated storage quota, however, increases to 25MB when application gets installed.

Additional reading
http://timheuer.com/blog/archive/2009/03/18/silverlight-3-offline-update-framework.aspx
http://msdn.microsoft.com/en-us/magazine/dd882515.aspx

Run the sample online

Source code below:

NTK09 – Slide decks from my talks

Had 2 talks at this year’s NT Konferenca.

The first one was about building LOB application with Silverlight, starting from what can we do today with v2 (ran a short, 2 min video of a Silverlight 2 LOB app we’re going to be releasing within few weeks) and what’s coming with v3. The last part was about .NET RIA Services.

The second talk was about Presentation Model (MVVM / Model-View-ViewModel) – from basics to actual working application – starting from a WPF version of an app, then porting the same ViewModel over to Silverlight to build a better UX and thorough testing, to finish with (again, with exactly the same ViewModel) a working version for Windows Forms (yes, that’s WinForms built with MVVM).

Fun.

Update: slides are in Slovenian language…

Dynamic Data Forms for Silverlight, revisited

A couple of weeks ago, I wrote a post about handling dynamic forms in Silverlight. With this continuation post, I’m going to make a few changes to the original project:

1. Implement a new, custom, field type and provide a template for it (I’ll write about it later), and
2. Make a few changes to the FormFieldTemplateSelector to make it more generic. So instead of writing templates like this:

A new TemplateSelectorDataTemplate…

<local:FormFieldTemplateSelector.StringTemplate>
    <DataTemplate>
        <TextBox Text="{Binding Value, Mode=TwoWay}" Width="100"/>
    </DataTemplate>
</local:FormFieldTemplateSelector.StringTemplate>
<local:FormFieldTemplateSelector.DateTimeTemplate>
    <DataTemplate>
        <basics:DatePicker SelectedDate="{Binding Value, Mode=TwoWay}" Width="100" />
    </DataTemplate>
</local:FormFieldTemplateSelector.DateTimeTemplate>

You could simply write:

<local:TemplateSelectorDataTemplate DataType="System.String">
    <TextBox Text="{Binding Value, Mode=TwoWay}" Width="100"/>
</local:TemplateSelectorDataTemplate>
<local:TemplateSelectorDataTemplate DataType="System.DateTime">
    <basics:DatePicker SelectedDate="{Binding Value, Mode=TwoWay}" Width="100" />
</local:TemplateSelectorDataTemplate>

You can see the DataType property on the TemplateSelectorDataTemplate used instead of using concrete templates like FormFieldTemplateSelecot.StringTemplate. This way, the FormFieldTemplateSelector’s DataType property can be matched with TemplateSelectorDataTemplate’s DataType property [long names confusion, I know] and you don’t have to factor a new template for each new field type you come with, making it feel a bit more like the DataTemplate implementation in WPF. Strings are used here instead of types. One reason for this is that Silverlight doesn’t support x:Type markup, and the second is the fact you can use any string to identify your field type: for example, you can use “#Signature#” string as a custom field type to insert a signature control into your form.

A written signature form field…

To demonstrate a support for custom field types, I created a special control, which will allow the user to sign herself on a special panel and the signature will be submitted to the server together with the other field values.

The control, which will allow us to write on it with the mouse, is of course InkPresenter. I’ve encapsulated it in another control, called SignaturePanel, which adds required mouse event handler which enables the user to write on the InkPresenter with a mouse. Here’s this control, contained within a new TemplateSelectorDataTemplate:

<local:TemplateSelectorDataTemplate DataType="#Signature#"> <local:SignaturePanel Width="100" Height="50"
Strokes="{Binding Value, Mode=TwoWay, Converter={StaticResource strokesConverter}}" /> </local:TemplateSelectorDataTemplate>

The template looks nothing special, except that strokesConverter, specified with the binding. What that does is serialize the Strokes collection from the InkPresenter when being written to the underlying ViewModel, where we need it when sending all submitted data over to the server side. This means that signature actually gets sent over the wire in a form of strokes collection, which you can store in a database. Alternatively, you could convert that strokes into the bitmap on the server and store the signature as an image [And I’ve yet to check how Silverlight 3 WritableBitmap can help doing this on the client]. Anyway, I’ve found StrokeCollection (de)serialization code in Julia Lerman’s Create Web Apps You Can Draw On with Silverlight 2 MSDN article and is included in the code sample attached to this post.

Here’s how the current form looks like:

image

Source code is now available. Please note that this is a Silverlight 3 project. It doesn’t contain any SL3 code, it’s just the project files were converted to SL3 when opened in Visual Studio.

All comments welcome. Enjoy.

Creating Silverlight Behaviors (with Blend 3 Interactivity dll)

Behaviors are not new in WPF / Silverlight world; it’s a common way of extending visual element’s behavior through the power of attached properties and everybody probably used one of these at least once in their projects. Now, there’s new Behaviors in town…

I first learned about the behaviors in this excellent, short but sweet MIX09 presentation by Pete Blois. In short: the new “breed” of behaviors will be supported in Blend 3, allowing designers to easily extend visual elements by drag’n’dropping a variety of behaviors onto them. If you’re not familiar with what behaviors are – imagine you have a Drag behavior... By setting it to any element in your window (in Blend / Xaml, no .NET code!), that element instantly gets draggable around that window. Yeah, that’s a powerful concept. And it doesn’t stop there. Watch the video, it’s worth the time…  And for detailed info, Christian is running a series on behaviors and other interactivity mechanism in his blog.

What I don’t get is why they are called Blend (3) behaviors, because they are not limited to Blend in any way. They would be as easily called Silverlight/WPF behaviors, or simply – Behaviors. Yes, that means you can use (and create) them even if you don’t have Blend 3 installed. Even Silverlight 3 is not required, it works with version 2 perfectly. You only need a special dll, which gets installed with Blend 3 – Microsoft.Expression.Interactivity.dll. I currently have no idea what the deployment story with this assembly is at the time of the writing (with Blend being in Beta and all), but you’ll find it in the c:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries\[Silverlight] | [WPF]\ folder. This assembly (it comes in Silverlight and WPF flavor) provides the base interactivity classes and is required if you’re going to use behaviors in your application.

It should be quite obvious as to where behaviors fit in the designer / developer workflow: designers will be able to decorate visual elements with various behaviors and see them in action, while developer’s job will be to come up with new, not-yet-existing behaviors that designer had in mind when designing the UX.

There are a few examples of behaviors up and ready on Expression Gallery, but let’s take a look how we can develop our own behaviors using Visual Studio 2008.

The first behavior we’ll look into will be called the TransparencyBehavior. What it will do is make every element semi-transparent when the mouse is not directly over it. I’ll use one of my previous samples (a semaphore) as a building ground for this one. The lights on the semaphore will be semitransparent until mouse enters the light’s space for it to become fully visible. Let’s begin

First, you’ll need the Expression interactivity dll (see above). Once you find it, add it as a reference to your project. Then, create a class, deriving from Behavior<T>. The generic type T is the type of element you want to extend with this behavior. I’m using the Ellipse type for the purpose of this example to show a more concrete implementation. I could also use <FrameworkElement> because this type of behavior is so common it could be attached to element.

Update: updated the previous paragraph to make sense and align with the sample code.

public class TransparencyBehavior : Behavior<Ellipse> {}

We’ll need a couple of properties to control the behavior’s parameter: The InactiveTransparency property will hold an opacity value for element’s inactive state (when the mouse is not over) and the Duration will hold the time for the element to transition from active to inactive state (and vice versa).

To hook into the element we’re extending, we have to override the OnAttached method. It will be called when the element is being initialized so we have the chance to attach additional event handlers to element’s events. The extended element can be reached through the AssociatedObject property. In this method, I’m hooking up into MouseEnter and MouseLeave events to detect when mouse is over, initialize and construct a storyboard that will be triggered for state transition:

protected override void OnAttached()
{
    base.OnAttached();

    storyboard = new Storyboard();
    animation = new DoubleAnimation();
    animation.Duration = Duration;
    Storyboard.SetTarget(animation, AssociatedObject);
    Storyboard.SetTargetProperty(animation, new PropertyPath(Border.OpacityProperty));
    storyboard.Children.Add(animation);

    AssociatedObject.Opacity = InactiveTransparency;
    AssociatedObject.MouseEnter += OnMouseEnter;
    AssociatedObject.MouseLeave += OnMouseLeave;
}
Similarly, there's the OnDetaching method that we can use to clean up (remove event handlers etc.) The rest of the class are just the handlers:
 
void OnMouseLeave(object sender, MouseEventArgs e)
{
    animation.To = InactiveTransparency;
    storyboard.Begin();
}

void OnMouseEnter(object sender, MouseEventArgs e)
{
    animation.To = 1;
    storyboard.Begin();
}
 
To finish, here’s a piece of modified (from the previous semaphore example) piece of Xaml using the behavior:
 
<Ellipse Fill="{Binding Brush}" Width="50" Height="50" Stroke="Black">
    <i:Interaction.Behaviors>
        <local:TransparencyBehavior Duration="00:00:00.2" InactiveTransparency="0.5" />
    </i:Interaction.Behaviors>
</Ellipse>
That’s all for this simple behavior. In future posts, I’ll come up with new behaviors and put them in the context of some other samples I’ve used in the previous posts.
[Hint: in the below sample, hover over green lights]

The way to create new behaviors is very similar to using “direct” approach with attached properties. The Behavior base class provides a very convenient infrastructure to build on, and porting the “old way” attached behaviors to this new model shouldn’t be that difficult. Behaviors are not limited to use in Blend 3 and work with Silverlight 2 too. With that, it would be great to see Microsoft releasing the interactivity dll as a standalone release or a part of some other SDK, not tying it to either Blend 3 or any particular Silverlight version.

The source code for this sample is available. Please note that the project is a Silverlight 3 project and doesn’t include the Expression Interactivity dll.

Update: the above code was updated to match Silverlight 3 / Blend 3 RTM bits. Thanks To Michael Washington for taking the time to update the behavior.

Shout it

Dynamic Data Forms for Silverlight with a Data Template Selector Control

The basic idea behind this post is to show a simple way for items/list controls to display each item data with a different template. The ideal candidate for such exercise are data forms, where user can enter different kinds of information - text, numbers, check marks, etc. Imagine a scenario, where each data form field would be presented as a separate ListBox item… no matter of what data type that field is.

The data model for this solution is going to be very simple and generic. We’ll need a generic class, which will represent a single field in a form. Each field will have an id, a caption, a value (entered by the user) and a value type (what’s the type of the value – text, integer, date, etc.):

public class AutoFormField
{
    public Guid Id { get; private set; }
    public string Caption { get; set; }
    public string Value { get; set; }
    public string Type { get; set; }

    public AutoFormField()
    {
        Id = Guid.NewGuid();
    }
}

When the user requests a form, the associated web service will return a collection of AutoFormFields, representing all fields in the form that user should fill out. I’m not using any database for this example, so I’ve hardcoded the fields, returning to the client, in the service itself:

public class AutoFormService : IAutoFormService
{
    public Collection<AutoFormField> GetForm()
    {
        Collection<AutoFormField> form = new Collection<AutoFormField>();
        form.Add(new AutoFormField()
        {
            Caption = "Name: ",
            Type = typeof(string).FullName
        });
        form.Add(new AutoFormField()
        {
            Caption = "Last name: ",
            Type = typeof(string).FullName
        });
        form.Add(new AutoFormField()
        {
            Caption = "Birth date: ",
            Type = typeof(DateTime).FullName
        });
        form.Add(new AutoFormField()
        {
            Caption = "Is employed: ",
            Type = typeof(bool).FullName,
            Value = false.ToString()
        });
        return form;
    }
}
 
The above code shows that the form consists of two text fields, a date and a yes/no field. We would naturally want to display TextBoxes for text entry, DatePicker for a date, and a CheckBox for a yes/no field entry. The Type property contains an identifier, which will tell the client what kind of entry field to display; field data type names are used here for convenience.
Let’s move to the client and implement this.
 
I’ll use the ItemsControl to display the items, because I don’t need the notion of a selected item (yet). Let’s first get the basics out of the way; this is how the ItemsControl looks like, displaying all the form’s captions:
 
<ItemsControl ItemsSource="{Binding Fields, Source={StaticResource viewModel}}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Caption}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
Its ItemsSource property is bound to a ViewModel’s Fields property, which gets populated when a call to the GetForm() web service method returns. The ItemTemplate is set up so that TextBlock displays the fields’ captions.

What we need to do next is display the actual entry fields the user will fill in. I already mentioned the Type property; this will be the key in deciding what kind of control to display.

If we would be coding this in WPF, we would use a DataTemplateSelector to help us out with selecting the right template to load for a specific type. Unfortunately, this feature is not implemented in Silverlight, so we’re on our own here. As it turns out, there isn’t much code required to come up with a solution. This is something that I call…

… a data template selector control…

For our example, we need templates for: a TextBox, a DatePicker and a CheckBox. The following user control will accept all these templates as properties and contain logic to choose between them based on a certain property, which will be bound to AutoFormField’s Type property:

public class FormFieldTemplateSelector : UserControl { public DataTemplate StringTemplate { get; set; } public DataTemplate DateTimeTemplate { get; set; } public DataTemplate BooleanTemplate { get; set; } public DataTemplate SignatureTemplate { get; set; } public static readonly DependencyProperty FieldTypeProperty = DependencyProperty.Register("FieldType", typeof(string), typeof(FormFieldTemplateSelector), new PropertyMetadata(string.Empty));

 

public string FieldType { get { return (string)GetValue(FieldTypeProperty); } set { SetValue(FieldTypeProperty, value); } } public FormFieldTemplateSelector() { Loaded += new RoutedEventHandler(OnLoaded); } private void OnLoaded(object sender, RoutedEventArgs e) { string fieldType = FieldType; if (fieldType == typeof(string).FullName) { Content = StringTemplate.LoadContent() as UIElement; } else if (fieldType == typeof(DateTime).FullName) { Content = DateTimeTemplate.LoadContent() as UIElement; } else if (fieldType == typeof(bool).FullName) { Content = BooleanTemplate.LoadContent() as UIElement; } else { Content = null; } } }

The way to set it up in the item template is simple too. Here’s the complete ItemTemplate:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition MinWidth="100" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <TextBlock Text="{Binding Caption}" VerticalAlignment="Center" />
    <local:FormFieldTemplateSelector Grid.Column="1" FieldType="{Binding Type}" Margin="0,2,0,2">
        <local:FormFieldTemplateSelector.StringTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Value, Mode=TwoWay}" Width="100"/>
            </DataTemplate>
        </local:FormFieldTemplateSelector.StringTemplate>
        <local:FormFieldTemplateSelector.DateTimeTemplate>
            <DataTemplate>
                <basics:DatePicker SelectedDate="{Binding Value, Mode=TwoWay}" Width="100" />
            </DataTemplate>
        </local:FormFieldTemplateSelector.DateTimeTemplate>
        <local:FormFieldTemplateSelector.BooleanTemplate>
            <DataTemplate>
                <CheckBox IsChecked="{Binding Value, Mode=TwoWay}" />
            </DataTemplate>
        </local:FormFieldTemplateSelector.BooleanTemplate>
    </local:FormFieldTemplateSelector>
</Grid>

Of course, this is just one way to put it together. You're free to style each field completely to your liking. This is what we have so far:

To wrap this up, you just have to add a button to submit the form back to the server. I’m not discussing this here since it’s pretty straightforward.

I will, however, continue to build up on this example in the next couple of posts. Some topics I’ll dig into is styling, positioning and more (interesting) templates. I’ll also post the full code in the final post of this series.

Disabling items in a Silverlight ListBox

This is a quick tip on making the ListBox items behave as disabled.

You know the semaphore, right? STOP on red, GO on green? OK. I’m drilling this with my two-year old when driving her to kindergarten every morning so lately it’s probably stuck in my mind a bit more than it should be.

OK. This is a ListBox:

image

Yes, it is:

<ListBox ItemsSource="{Binding Lights}" BorderThickness="0">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Ellipse Fill="{Binding Brush}" Width="50" Height="50" Stroke="Black" Cursor="Hand" />
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem" >
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <ContentPresenter x:Name="contentPresenter" Margin="4" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

The data context of this ListBox is a ViewModel with the Lights property. Lights is a collection of five Light objects.

One property that the Light object exposes is the Brush property; it will simply point to a solid color brush of a red, yellow or green color, respectively. The Ellipse’s Fill property is bound to the Brush property as can observed in the above code.

Semaphores usually change colors in an order. The ones in this sample will blink randomly, changing their colors in 2 second intervals:

public Light()
{
    this.SetColor();
    DispatcherTimer timer = new DispatcherTimer()
    {
        Interval = TimeSpan.FromSeconds(2.0)
    };
    
    timer.Tick += (s, e) => { this.SetColor(); };
    timer.Start();
}

private void SetColor()
{
    Color[] colorArray = new Color[] { Colors.Red, Colors.Yellow, Colors.Green };
    Color color = colorArray[randomizer.Next(0, 3)];
    this.Brush = new SolidColorBrush(color);
    this.IsEnabled = color == Colors.Green;
}

Now, we want to allow the user click only on green light, OK? The last line in the above SetColor method sets the IsEnabled property on the Light object only when the current color is set to Green.

With the IsEnabled property up and about, it gets really easy. To prevent the user from clicking on the ListBox item, simply set bind its IsHitTestVisible property to IsEnabled property on the Light class (bold underlined part added):

<ControlTemplate TargetType="ListBoxItem">
    <ContentPresenter x:Name="contentPresenter" Margin="4" 
        IsHitTestVisible="{Binding IsEnabled}" Cursor="Hand" /> </ControlTemplate>

[Cursor property is there for instant visual feedback on when the item is enabled]

That’s it, really. You can test it by adding i.e. a Click event handler to the contentPresenter and display a message box or something (included in the sample below). You would also want to build a better templates for the enabled/disabled items. If built around the bound IsEnabled property, it should work fine.

Declarative Role-based “security” for Silverlight Xaml elements

Tim Heuer published a great example on how to implement user authentication and role validation with ASP.NET Application Services in his Application Corner a while ago. It really works as expected, even with custom membership / role providers. And you get to do declarative role based security checks on your server side classes too.

When building MVVM pattern applications, you tend to have as less code as possible in your views’ code-behind classes. Call me a MVVM purist [ :), see Tim’s video interview for pixel8 ], but (close to) zero lines of custom code is what I like to have in my code-behinds. Not at all costs, but usually it doesn’t take much to code additional helper class, an attached property or a controller of some sort.

What I wanted to do, was replace the following piece of code with something more declarative, which could be used in Xaml:

private void EnableAppFeatures(ObservableCollection<string> roles)
{
    EmployeeButton.IsEnabled = (roles.Contains("Admin") || roles.Contains("HR"));
    OrderButton.IsEnabled = (roles.Contains("Admin") || roles.Contains("Sales"));
    CustomersButton.IsEnabled = (roles.Contains("Admin") || roles.Contains("Sales"));
    ReportsButton.IsEnabled = (roles.Contains("Admin") || roles.Contains("Sales"));
}

[the roles string collection comes in as a result of the Roles service call]

Solution #1 - Good

If you’re using MVVM, adding some additional properties to your ViewModels (like IsInHRRole, IsInSalesRole, etc) should be easy, right? You would just need to bind al the buttons’ IsEnabled properties to their ViewModel counterparts and you’re done.

<Button ... x:Name="ReportsButton" ... IsEnabled="{Binding IsInSalesRole}">

True, but you’ll probably end up “polluting” all your ViewModels with such properties since usually the majority of the Views have some elements, depending on a role the user is in. Additionally, you’d have to create additional properties for combined roles, e.g. IsInSalesOrAdminRole,

Solution #2 - Better

I was thinking somewhere in the lines of attaching a new attached property to each button, which would enable the button when the user would be in one of the specified roles:

<Button ... x:Name="ReportsButton" ... sec:SecurityAction.DemandRole="Sales,Admin">

SecurityAction.DemandRole in this case is an attached property, specifying all the roles, which would make the button enabled. The logic is simple – if the user is in one of the specified roles, the button (or any other control with this attribute appended) would have its IsEnabled property set to true. 

To make this possible, I first had to come up with a class to hold all the current roles, something like a Principal… This is a short class, supporting roles only that will do a job for this demonstration:
 
public class SilverlightPrincipal
{
    public static ObservableCollection<string> Roles { get; private set; }

    static SilverlightPrincipal()
    {
        Roles = new ObservableCollection<string>();
    }

    public static void SetRoles(IList<string> roles)
    {
        Roles.Clear();
        for (int i = 0; i < roles.Count; i++)
        {
            Roles.Add(roles[i]);
        }
    }
    public static bool IsInRole(string role)
    {
        return Roles.Contains(role);
    }

    public static bool IsInOneOfRoles(string[] roles)
    {
        for (int i = 0; i < roles.Length; i++)
        {
            if (Roles.Contains(roles[i]))
            {
                return true;
            }
        }
        return false;
    }
}

The roles collection will contain all roles the user is currently in. IsInRole() and IsInOneOfRoles() will return true, if user is in one of the passed in roles. The SetRoles() method is here for simplicity – it servers just as a roles setter, called from wherever the Roles service calls returns.

Perhaps the class above probably doesn’t even deserve to be called a Principal, but it will serve well for the purpose of this post. For more ideas to implement a more complete Silverlight Principal, check this blog post.

To plug it in Tim’s code, I used the aforementioned EnableAppFeatures method, which now looks like:

private void EnableAppFeatures(ObservableCollection<string> roles)
{
    SilverlightPrincipal.SetRoles(roles);
}

The next thing to do was create the SecurityAction.DemandRole attached property that could be used to set the required roles to a specific control. You’ll find this attached property in the sample code attached to this post. I’m not including the code here because it will make this post much longer and I’m not really fond of using it anyway, because of the reasons for solution #3 below. However, feel free to try the property and please leave comment if you like (or dislike) it.

Solution #3 - Best

After creating #2, I thought – if user can never access the functionality behind the buttons, there is no need to show the buttons to her in the first place, right? Why not showing her the dashboard, created specifically for her role? Sounds familiar? ASP.NET? LoginView?

Here’s my simple LoginView control for Silverlight. You can define as many LoginView templates for as many roles you have:

<controls:LoginView>
    <controls:LoginView.Templates>
        <controls:LoginViewDataTemplate Roles="HR>
            <!-- Layout for HR role -->
        </controls:LoginViewDataTemplate>
        <controls:LoginViewDataTemplate Roles="Sales>
        <!-- Layout for Sales role -->
        </controls:LoginViewDataTemplate>
        <controls:LoginViewDataTemplate Roles="Admin>
            <!-- Layout for Admin role -->
        </controls:LoginViewDataTemplate>
     </controls:LoginView.Templates>
</controls:LoginView>
 
First, here’s the LoginViewTemplate class:
 
public class LoginViewDataTemplate : DataTemplate
{
    public string Roles { get; set; }
}
Yeah, that’s pretty much it. The Roles property will hold the list of roles, which are allowed to see the template.
 
The LoginView control itself is simple too:
 
public class LoginView : UserControl
{
    public Collection<LoginViewDataTemplate> Templates { get; set; }

    public LoginView()
    {
        Templates = new Collection<LoginViewDataTemplate>();

        SilverlightPrincipal.RegisterForRoleChangeNotification(this, LoadTemplate);
        Loaded += (s,e) => { LoadTemplate(); };
    }

    private void LoadTemplate()
    {
        for (int i = 0; i < Templates.Count; i++)
        {
            string[] roleNames = Templates[i].Roles.Split(new char[] { ',', ' ' }, 
                StringSplitOptions.RemoveEmptyEntries); bool isInRole = SilverlightPrincipal.IsInOneOfRoles(roleNames); if (isInRole) { Content = Templates[i].LoadContent() as UIElement; return; } } Content = null; } }

[Update 06-13: updated the above code; should work now]

There’s not much to comment here… The Templates collection holds the collection of, errr., LoginViewDataTemplates, and the LoadTemplate method is there to Load the first template, having one of the specified roles match the current role that user is in. This could be easily extended to support the default template, if needed. The default template would be loaded when no other template would match the current user’s role.

RoleChanged notification /execution

The right template is loaded with the control and whenever the Roles might change, the control would reload the template. I’ve implemented this behavior by adding a registration method for role change notification. Any visual element (or whatever object for that matter) can register itself by passing in the delegate to whatever method should be called whenever role(s) would change. The registration method was conveniently added to existing SilverlightPrincipal class:

public static void RegisterForRoleChangeNotification(object o, Action action)
{
    bool existsInCollection = references.Keys.FirstOrDefault(reference => reference.Target == o) != null;
    if (!existsInCollection)
    {
        references.Add(new WeakReference(o), action);
    }
}

Whenever the roles would change, register objects’ delegate would be called:

private static void OnRolesChanged()
{
    CleanUp();
    foreach (var reference in references)
    {
        reference.Value();
    }
}

The CleanUp method takes care for dead/disposed objects:

private static void CleanUp()
{
    List<WeakReference> list = references.Keys.ToList<WeakReference>();
    for (int i = list.Count - 1; i >= 0; i--)
    {
        WeakReference r = list[i];
        if (!r.IsAlive)
        {
            references.Remove(r);
        }
    }
}

Classes, included in the package: SilverlightPrincipal, SecurityAction, LoginView:

Binding to Enums

I’ve seen numerous questions regarding data binding to Enums, together with many solutions on how to do it, but the question I’m asking myself is – do I really want to bind anything to an Enum?

I like to think about Enums purely as a coding aid – to help programmer code with some descriptive names instead of messing with pure numeric values. Similar to what constants are for, except Enums provide a set of values for describing a single parameter.

Instead of:

product.Quality = 3;

the programmer would write:

product.Quality = Quality.Good;
 
… providing that Quality Enum is declared something like:
 
public enum Quality
{
    JustBad, Poor, OK, Good, Excellent
}

Of course, you could set your enum values to some concrete numbers, like:

public enum Quality
{
    JustBad = 1, Poor = 2, OK = 3, Good = 4, Excellent = 5
}

… but in most cases you shouldn’t need to. Like I said, I see Enums only as a before-compilation, human <-> code communication, and therefore I believe no part of Enum should ever see the light of day (i.e. be exposed to the UI). And with that, there goes the need for binding to Enums…

Why would I want to bind to Enums anyway? Enum enumerators have no description (other than their names). If you need to provide spaces or even support localized descriptions, you’ll need to extend them significantly, so why not create a new class anyway? Here’s what I use instead of an Enum:

public sealed class Quality
{
    public const int JustBad = 1;
    public const int Poor = 2;
    public const int OK = 3;
    public const int Good = 4;
    public const int Excellent = 5;

    public Dictionary<int, string> Collection { get; private set; }

    public Quality()
    {
        Collection = new Dictionary<int, string>()
        {
            {JustBad,   "Just bad :("},
            {Poor,      "Poor"},
            {OK,        "OK"},
            {Good,      "Good"},
            {Excellent, "Excellent!"},
        };
    }
}

The programmer would still write:

product.Quality = Quality.Good;

so it makes it easy to refactor existing code. Additionally, you can put in any description for the values, support localization, and it’s easy bindable in Xaml - declare the class instance as a local resource:

<local:Quality x:Key="quality" />
and bind away:
 
<ListBox DisplayMemberPath="Value" 
         ItemsSource="{Binding Collection, Source={StaticResource quality}}" />

WPF vs. Silverlight: a subset or what?

For a WPF developer, crossing over to Silverlight development can be a pretty mindboggling adventure.

I mean - if you’re currently engaged with Windows Forms or ASP.NET and seeking new advancements, Silverlight would (should?) be a logical step forward in your life as a developer. There are, of course, a whole variety of new concepts and patterns to be learned, but compared to WPF, Silverlight is really not that big. When comparing Silverlight and WPF, I often describe WPF as Silverlight’s older brother: calm, capable & wise business man, dressed in a grey suit. On the other hand, Silverlight would be a very agile, very smart and witty teenager, popular among the crowd, although sometimes crossing the boundaries of what’s considered a good behavior. But at the same time he would be pushing the tolerance limits of his older brother, teaching him some new things and giving him a different, fresh perspective on life.

How so?

WPF is pretty big, framework-wise. Silverlight is substantially smaller, but:

a] Silverlight had Visual State Manager in v2. WPF VSM was announced only after Silverlight was out and is in the making, as of now. VSM was introduced to replace styling with the support of triggers, which don’t really exist in Silverlight (there’s the EventTrigger, but that’s pretty much it).
b] Silverlight had a DataGrid in v2. WPF DataGrid v1 has just been released.
c] Silverlight additionally allows some simpler Xaml constructs, like TargetTyping to a type name (TargetType=”Button”) rather than a type reference (WPF: TargetType=”{x:Type Button}”), etc. WPF is going to follow Silverlight on this too.

Silverlight clearly took the lead with introducing new features into the framework and improving what was considered as not so good in WPF. And with Silverlight v2 being RTW for only a few months now, we’re expecting some big announcements on MIX09about v3 , which is said to be released later this year. Silverlight is maturing fast.

Of course, there are currently some crucial things missing in Silverlight that ruins the experience with developing a decent (LOB) application:

a] No commanding support.
b] No real business objects validation support.
c] etc, etc… The web is full of Silverlight missing features. Google it. I’ll only post two MSDN links on differences between WPF and Silverlight: here, here.

If you’ve learned (and practiced) WPF prior to Silverlight, those differences could easily turn out to be a wall, which you’re going to hit into when actively engaged in developing a real-world Silverlight project. Take, for example, the DependencyObject. The guy who posted this question obviously studied the wrong documentation when learning Silverlight. And it’s so easy to take a wrong turn when navigating through the links describing Silverlight classes and functionality. One wrong click and you may be directed to the WPF-version of the page, describing DependencyObject, for example. Not knowing that you’re really studying the WPF implementation (which differs significantly from what’s in Silverlight) you read all about it; and you learn it wrong!  I myself didn’t know about this difference until the mentioned post got me to start Reflecting on both versions of DependencyObject.

Here’s the short story: if you declare a DependencyProperty on the DependencyObject in WPF, any change to the value of this property will raise the PropertyChanged event, without the need to implement the INotifyPropertyChanged interface. In Silverlight, this is no go. Silverlight’s DependencyObject doesn’t implement the OnPropertyChanged method like WPF DO does, so you have to implement INotifyPropertyChanged interface on your object for it to properly propagate PropertyChanged event to its listeners. There is, however, a reasoning behind this: Silverlight’s Binding construct doesn’t support the ElementName property, which allows binding to some other control on the same page. All controls are descendants of a DependencyObject so therefore, if bound to, they should notify their listeners if one of dependency properties has changed. But because you can’t bind to those controls, there is no need for DependencyObjects to support PropertyChanged notification on dependency properties. You commonly bind your controls to business objects in Silverlight anyway, and putting DependencyProperties into business objects is not recommended even in WPF. Business objects should implement INotifyPropertyChanged-enabled properties, be that in Silverlight or WPF.

All those tiny little differences don’t make it easy for someone concurrently involved with Silverlight and WPF projects. Imagine working on two simultaneous projects, but one in C# and the other in VB. The syntax differences of those two can be easily compared to differences between Silverlight and WPF. Constantly switching between two similar mindsets can be a pain.

We’ve all been told several times that Silverlight is a subset of WPF. Well, rather than a subset, I like to call Silverlight a REset of WPF. I mean, with Silverlight, Microsoft now has this great opportunity to gradually create a fresh, true cross-platform, “runs-everywhere” presentation framework from the ground up, being able to cover all kinds of applications imagined, from games to business; the latter of course greatly powered by the web (services / cloud). They’ve learned what works and what not from working on WPF, so Silverlight would get only those bits that do work. At the same time WPF will continue to improve together with Silverlight, until… until Silverlight grows powerful enough to forget all about WPF :) Might be far-fetched, but hey…

So, will WPF eventually die? Is it a dead end? When?
Let me answer this question with another answer: is Windows Forms dead yet?

On the other hand, look what we’ve been programming about 10-15 years ago… looking 15 years in the future, I’m afraid there will be neither Silverlight nor WPF, but something uber-both. So whatever solves your current business problem, goes.

WPF vs. Silverlight: a subset or what?

For a WPF developer, crossing over to Silverlight development can be a pretty mindboggling adventure.

I mean - if you’re currently engaged with Windows Forms or ASP.NET and seeking new advancements, Silverlight would (should?) be a logical step forward in your life as a developer. There are, of course, a whole variety of new concepts and patterns to be learned, but compared to WPF, Silverlight is really not that big. When comparing Silverlight and WPF, I often describe WPF as Silverlight’s older brother: calm, capable & wise business man, dressed in a grey suit. On the other hand, Silverlight would be a very agile, very smart and witty teenager, popular among the crowd, although sometimes crossing the boundaries of what’s considered a good behavior. But at the same time he would be pushing the tolerance limits of his older brother, teaching him some new things and giving him a different, fresh perspective on life.

How so?

WPF is pretty big, framework-wise. Silverlight is substantially smaller, but:

a] Silverlight had Visual State Manager in v2. WPF VSM was announced only after Silverlight was out and is in the making, as of now. VSM was introduced to replace styling with the support of triggers, which don’t really exist in Silverlight (there’s the EventTrigger, but that’s pretty much it).
b] Silverlight had a DataGrid in v2. WPF DataGrid v1 has just been released.
c] Silverlight additionally allows some simpler Xaml constructs, like TargetTyping to a type name (TargetType=”Button”) rather than a type reference (WPF: TargetType=”{x:Type Button}”), etc. WPF is going to follow Silverlight on this too.

Silverlight clearly took the lead with introducing new features into the framework and improving what was considered as not so good in WPF. And with Silverlight v2 being RTW for only a few months now, we’re expecting some big announcements on MIX09about v3 , which is said to be released later this year. Silverlight is maturing fast.

Of course, there are currently some crucial things missing in Silverlight that ruins the experience with developing a decent (LOB) application:

a] No commanding support.
b] No real business objects validation support.
c] etc, etc… The web is full of Silverlight missing features. Google it. I’ll only post two MSDN links on differences between WPF and Silverlight: here, here.

If you’ve learned (and practiced) WPF prior to Silverlight, those differences could easily turn out to be a wall, which you’re going to hit into when actively engaged in developing a real-world Silverlight project. Take, for example, the DependencyObject. The guy who posted this question obviously studied the wrong documentation when learning Silverlight. And it’s so easy to take a wrong turn when navigating through the links describing Silverlight classes and functionality. One wrong click and you may be directed to the WPF-version of the page, describing DependencyObject, for example. Not knowing that you’re really studying the WPF implementation (which differs significantly from what’s in Silverlight) you read all about it; and you learn it wrong!  I myself didn’t know about this difference until the mentioned post got me to start Reflecting on both versions of DependencyObject.

Here’s the short story: if you declare a DependencyProperty on the DependencyObject in WPF, any change to the value of this property will raise the PropertyChanged event, without the need to implement the INotifyPropertyChanged interface. In Silverlight, this is no go. Silverlight’s DependencyObject doesn’t implement the OnPropertyChanged method like WPF DO does, so you have to implement INotifyPropertyChanged interface on your object for it to properly propagate PropertyChanged event to its listeners. There is, however, a reasoning behind this: Silverlight’s Binding construct doesn’t support the ElementName property, which allows binding to some other control on the same page. All controls are descendants of a DependencyObject so therefore, if bound to, they should notify their listeners if one of dependency properties has changed. But because you can’t bind to those controls, there is no need for DependencyObjects to support PropertyChanged notification on dependency properties. You commonly bind your controls to business objects in Silverlight anyway, and putting DependencyProperties into business objects is not recommended even in WPF. Business objects should implement INotifyPropertyChanged-enabled properties, be that in Silverlight or WPF.

All those tiny little differences don’t make it easy for someone concurrently involved with Silverlight and WPF projects. Imagine working on two simultaneous projects, but one in C# and the other in VB. The syntax differences of those two can be easily compared to differences between Silverlight and WPF. Constantly switching between two similar mindsets can be a pain.

We’ve all been told several times that Silverlight is a subset of WPF. Well, rather than a subset, I like to call Silverlight a REset of WPF. I mean, with Silverlight, Microsoft now has this great opportunity to gradually create a fresh, true cross-platform, “runs-everywhere” presentation framework from the ground up, being able to cover all kinds of applications imagined, from games to business; the latter of course greatly powered by the web (services / cloud). They’ve learned what works and what not from working on WPF, so Silverlight would get only those bits that do work. At the same time WPF will continue to improve together with Silverlight, until… until Silverlight grows powerful enough to forget all about WPF :) Might be far-fetched, but hey…

So, will WPF eventually die? Is it a dead end? When?
Let me answer this question with another answer: is Windows Forms dead yet?

On the other hand, look what we’ve been programming about 10-15 years ago… looking 15 years in the future, I’m afraid there will be neither Silverlight nor WPF, but something uber-both. So whatever solves your current business problem, goes.