Wednesday, July 16, 2008

How Do You Change the Cursor of a WPF App?

Changing the cursor of a WPF app is pretty simple. You can do it through procedural code as follows:
this.Cursor = Cursors.None;

There are several built in cursors such as a pen, cross, scroll, etc.
You can also use a custom cursor as follows:
this.Cursor = new Cursor("CustomCursorImage.jpg");

Because Cursor is a dependency property, it can also be used in XAML. Here are two examples on how to use custom cursors via XAML:

<Button Content="Wait" Cursor="Wait"/>

<Button Content="CustomCursorImage.jpg"/>

What timer to use for WPF and Silverlight Applications

When working on WPF or Silverlight Applications, instead of using your typical .Net timers, developers should stick with the DispatcherTimer. Handlers for the DispatcherTimer are invoked on the UI thread, so you don't have to worry about threading issues. The DispatchTimer class is located in the System.Windows.Threading namespace. To use it, you set an Interval property from a TimeSpan property, add a handler for the Tick event and call the start method to start the timing.

//------------------------------------------
//DispatcherTimer code snippet
//------------------------------------------

DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(100);
timer.Tick += timerOnTick;
timer.Start();

void timerOnTick(object sender, EventArgs args)
{
//do something
}

Very Cool Silverlight Example

Silverlight is very powerful. It is a relatively new technology, so it is not as advanced in some aspects as its rival Flash. Microsoft is rapidly adding new features to make it comparable to Flash. In my opinion, Silverlight is much better than Flash now. I have developed a few flash applications using Adobe Flex. I have also worked on an Adobe AIR application. Adobe has done some pretty cool things to make Flash development easier, but the main drawback is that I have to become familiar with ActionScript.

With Silverlight, I can keep developing in C#! (I also think XAML is more powerful than MXML)

Check out the link above to see an example of what can be done with the current Silverlight bits.

WPF and Silverlight Best Practice: Event Handlers


When developing WPF and Silverlight applications, developers and designers can create a clean line of separation between the look and feel of the application and its functionality. This is possible because of XAML. Although it is possible to create WPF or Silverlight applications entirely of procedural code (VB or C#), it is highly unlikely you would see such an application. Typically, designers work on the XAML files while developers work on the code behind files. In the XAML files, designers can specify what the UI looks like, while developers deal with the behavior. It is possible, however, for designers to embed some basic functionality within the XAML itself. One example is in defining event handlers. In the following code snippet I am defining a button.

<Button x:Name="btnSave" Content="Save" Width="90" Height="25" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="118,0,0,11.33899974823" Click="MyClickHandler"/>

This button has various properties that define its look and feel including Content, Width, Height, etc. I have also specified an event handler for the button's Click event. The body of this even handler is found in the code behind file of my Silverlight or WPF control. This code is perfectly legitimate. In fact, it can clean up your code behind files significantly. If you have 50 buttons, each of which need to point to this event handler, it removes a lot of these statements.


btnSave.Click += new RoutedEventHandler(MyClickHandler);

This was my reasoning when I first started writing WPF apps. I thought I would clean up my .cs files as much as possible. If I could write it in XAML, I would. There is a small problem with this approach. Lets say the XAML snipped above was found in a xaml file that was then handed off to a designer. The designer opens it up in a design tool like Expression Blend and decides the button looks terrible with all those attributes. Instead, he/she wants the button to look a lot different, so he/she decides to completely wipe out that button and start from scratch. As long as there is a button named btnSave, the application should build. So, he/she ends up with this

<Button x:Name="btnSave" Content="Click to Save" Style="{StaticResource SaveButtonStyle}" Margin="0,4.5,2,0" VerticalAlignment="Top" d:LayoutOverrides="Height"/>

This button now has a completely different look and feel. It points to a style resource which may drastically change the appearance of the button. At this point the designer builds the application and there are no errors, so he/she is happy. There have been no breaking changes and the button looks great…. WRONG! Although the application builds and it looks great, there has been a major change in the behavior of the button. With the following code, there is no handler for the click event. The designer accidentally wiped out the old XAML not realizing that a little bit of functionality had been defined there. This is the problem with defining event handlers inside XAML code.

As a best practice… Always assign your event handlers in your procedural code. Here is what I do… Inside the constructor of all my WPF and Silverlight controls, I add a method called AddEventHandlers(). Inside this method, I take care of adding the event handler to all my controls defined in my XAML. The code looks something like this:


public MyControl()

{

InitializeComponent();

AddEventHandlers();

}

private void AddEventHandlers()

{

btnSave.Click += new RoutedEventHandler(MySaveClickHandler);

btnExit.Click += new RoutedEventHandler(MyExitClickHandler);

btnOk.Click += new RoutedEventHandler(MyOkClickHandler);

}