Hi again in the second part of discovering Behaviors in WPF/Silverlight with Expression Blend. In the previous part, we have seen how to build simple behaviors in code using Visual Studio 2010. In this post, I’m going to extend that and see how to use a “busy state indicator” as a behavior to signal the state of business in your application.
The other day, I was trying to include a busy indicator in my application. I didn’t want to build this from scratch, and instead wanted to use one of the behaviors available online. I found one in the Expression Community Gallery that is called Busy State Indicator Behavior by Pedro Pombeiro. This one is great since it is built as a reusable behavior, customizable, and makes use of a great indicator built by Sasha Barber, a Circular Progress Bar. Both form a perfect match of what I want. Details of how to use that in an application follow in this post.
Setting the stage:
In order for us to be on the same page, make sure you have the following in place:
Building an application that uses Busy State Indicator Behavior:
1. Create a project in Visual Studio:
Give the project a name, I have named my project Behaviors101.
2. Build the busy state context:
I mean by that the logic needed to indicate when you’re application is busy. I will build that as a custom class in my project, which will provide two properties (IsBusy and BusyText) designating flag for business and an optional text for elaboration on what your application is busy on. Below is the initial code for this class that I have named BusyState.cs.
3. Use the busy state context in your application:
This step is more of just a reference and instantiation of the BusyState class outlined above. You can do that either in code or XAML. I have chosen to do that in XAML and made that possible by referencing the namespace of my application to get access to the BusyState class:
4. Build the functionality to use the busy state context:
Since I don’t have a functionality for this application, I’m gonna resemble its state of being busy by a timer. The timer will signal the application from busy to free upon the ticks of the clock. You may change that with your own logic such as asynchronous internet connections, database queries, or any other long running processes. Below is the code snippet that declares the timer, initializes it, and wires the event of ticking.
Notice how I have obtained a reference to the static resource BusyStateObject in line 21, which enables me then to change the busy flag and text.
5. Test out your application busy state by binding to UI
Before we go ahead with the behavior, let’s do a quick test on the above. I’m gonna bind the BusyStateObject with two elements in the UI in XAML: a textblock and a checkbox. This will enable us to do a quick check on whether the above is working.
The binding as you can see (in line 3 and 5) is simple: Text property (target property) of the TextBlock (target object) gets its value from the static resource defined above as BusyStateObject (source object) with a path to BusyText (source property). Same goes for IsChecked of the CheckBox.
Once you do this in XAML, you’ll see that design time immediately reflects on the BusyStateObject properties by setting IsChecked to false and Text to “None”. Now, if you run the application (F5) you will expect that the binding will do the job once the timer kicks in. Unfortunately that is not the case!
Although the timer does its job, you’ll find that changes to your BusyStateObject properties (IsBusy and Text) doesn’t have an effect on the UI and the bound properties, and that is caused by the fact that your application has no clue at all of the changes on those properties. Looking around for a solution will guide you to this article (WPF Basic Data Binding FAQ). In this article, you’ll see a solution to this problem which is all about implementing a notification (with events) when property values change by letting your class implement the interface INotifyPropertyChanged. The code changes to BusyState.cs conclude it as follows:
with that, go ahead and run your application and see how that the textblock and checkbox change values every 5 seconds.
6. Importing the Busy State Indicator Behavior:
The previous step enabled us to test out the application busy state and making sure everything is working fine. Of course the goal is to use a better busy state indicator UI instead of the the checkbox and textblock, so we’ll now use the BusyStateIndicator Behavior.
If you have successfully downloaded the behavior from the gallery, you’ll see that you have two components (3 files in total):
With that, all you need to do is to include those files into your project, and reference the BusyStateIndicator behavior namespace in XAML. I have renamed the namespace in the imported files to Behaviors101 to make it simpler for me to reuse the previously used xmlns:local reference.
7. Using the BusyStateIndicator Behavior:
Now all files are imported to your project and referenced properly, you only need to look for the grid you want to target for the busy state behavior and attach the behavior. Also, you need to bind the BusyState property of the behavior to the whatever tells it to go busy (BusyStateObject.IsBusy is the one in our case).
Notice how that I have set the DataContext for data binding to the static resource BusyStateObject in line 2. Then I have used simple binding in line 3 to bind BusyState of the behavior (the target property) to IsBusy (the source property). In line 4, TargetVisual is bound to a relative source which is the Grid in this case.
Run the application now, and you’ll see that the circular bar fades in whenever the timer ticks, and gradually fades out on the next tick.
We have learned in this post how to use the BusyStateIndicator behavior and the attached Circular Progress Bar. The idea was to reuse an existing behavior available from the Expression Community Gallery, and setting the stage for using it with a busy state object/flag. A future post will utilize this behavior in a more practical way, but I wanted to detail the steps for you to use in your projects leveraging WPF and behaviors.
This post aims at working with behaviors in Windows Presentation Foundation (WPF) via Visual Studio 2010 and Expression Blend Preview for .NET 4. I will start with the basics and follow up with posts to work on some of the details.
Behaviors are basically objects that encapsulate triggers (usually caused by external events) and actions that represent the operations to purpose the behavior. Behaviors have been introduced in Expression Blend 3 and are supported in both WPF and Silverlight to provide interactivity without code. They can be designed in Blend or coded in Visual Studio. To start off, we’re going to build a simple behavior and will code it in Visual Studio 2010 (yeah, the hard way gets you learning!). The behavior is going to be attached to a button and will have simple actions like displaying a message or changing the background.
Here are the steps to do build your first behavior:
1. Create a new Project in VS2010 – Choose WPF Application and give it a name:
I have named my project Behaviors101. One important thing to note here is to make sure you target the appropriate .NET framework based on the tools you use. For example, choose .NET Framework 3.5 with Visual Studio 2008 and Expression Blend 3. If you’re a beta savvy, then get your hands on the beta version of Visual Studio 2010, and Expression Blend Preview .NET 4. With the latter ones, make sure you target .NET 4.0 so you can open the project in both VS and Blend.
2. Add a new class file to your project ButtonBehaviors101.cs with following code:
3. Make sure of proper assembly references are in place for your new Behavior:
3. Make sure of proper assembly references are in place for your new Behavior:
If you’re working against .NET 3.5, then use Microsoft.Expression.Interactions. If in .NET 4.0 then use System.Windows.Interactivity as this functionality will move to the core platform in .NET 4.0. After that, use proper using statement according to your reference.
4. Make proper references In XAML:
In order for us to wire up our simple behavior and attach it to a button, we need to reference the proper assemblies in XAML as well. Also, you need to reference your current namespace to get access to the custom class ButtonBehavior101.
5. Wire up your XAML control to the newly created behavior:
Now, when you run your application and click the button, and you’ll see your behavior in action which basically displays a message box saying: Hello from Behaviors.
You may ask now why to behaviors? And the rational is that you can package it and make reusable (attache-able) to different objects (Buttons in our example). Also, when you decide to change the behavior then your client (the attached object) doesn’t need to change anything from his side.
So, let’s change the behavior action and proof that we don’t need to touch our main application. We’ll do that by changing the behavior to change a property of the button, instead of showing a message box. We will change the background this time.
6. Change the code of the associated click event to be the following:
Run the application and you’ll find that the button changing behavior based on the changes you have made to the ButtonBehavior101 class.
One interesting thing will happen as well. The button will not only change the background, but will start fading the background color in and out instead of turning it to the value assigned. This is caused by a default action triggered upon keyboard focus. To check what’s behind the scenes, we can open the project in Expression Blend, and discover that default trigger in design mode.
1. Open the project in Expression Blend:
Make sure you use the right tools together. Blend 3 works with Visual Studio 2008 and Blend Preview for .NET 4 works with Visual Studio 2010.
2. Edit the button template to access the internals of button components:
Right-click on the button in Blend, and choose Edit Template -> Edit a Copy.
You’ll be presented with a Create Style Resource dialog, accept the defaults and click OK.
3. Access the triggers to find out that focus is behind the fading behavior:
While in the palette of the button, click on "Triggers" tab and you’ll be presented with a number of triggers. One of them is conditioned on IsKeboardFocused and the action is setting Chrome.RenderDefaulted to true. This action enables or disables the fading behavior. The question now is why it’s fading, and my guess for now is that it relates to the Windows theme in use. A subject of research in the futureJ !
We have seen how to create a simple behavior from scratch in code, and how changing that behavior simply doesn’t require us recoding on the client that uses this behavior. Of course coding is not the optimal way, and in the future we’ll discover how to design complex behaviors in Blend without writing code.
Stay tuned for more posts.
It took me sometime until I figured out some facts about Web Parts lifecycle. The following are some findings I believe will make you rethink what methods and events to override to develop a Web Part:
Few posts that could be helpful:
If you like to be more productive in WSS development, you can always use Visual Studio Extensions for Windows SharePoint Services 3.0.
Visual Studio 2005 -> VseWSS 1.1
Visual Studio 2008 -> VseWSS 1.2
Then, set the “Start Browser with URL” to your Web App URL. With that, you can enjoy the Deply (solution packaging, deployment, and activation) funtionalities provided by the extensions.
Always remember your SharePoint Development source: http://www.MSSharePointDeveloper.com!
Here is a sample batch file to help with your SharePoint development on Windows Server 2008 and IIS 7.0.
@SET TEMPLATEDIR=”c:\program files\common files\microsoft shared\web server extensions\12\Template”
@SET STSADM=”c:\program files\common files\microsoft shared\web server extensions\12\bin\stsadm”
@SET GACUTIL=”C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\gacutil.exe”
Echo Installing YOURASSEMBLY.dll in GAC
%GACUTIL% -if bin\debug\YOURASSEMBLY.dll
REM You can also deploy to local bin folder of the Web Application, if you don’t want or not allowed to use GAC
REM Echo Copying YOURASSEMBLY.dll to Web App Bin
REM xcopy /y bin\debug\YOURASSEMBLY.dll C:\inetpub\wwwroot\wss\VirtualDirectories\80\bin
Echo Copying files
xcopy /e /y TEMPLATE\* %TEMPLATEDIR%
Echo Installing feature
%STSADM% -o installfeature -filename YOURFEATURES\feature.xml -force
Echo Recycling Application Pool
%APPCMD% recycle APPPOOL “SharePoint – 80″