Wednesday, January 22, 2014

Dynamically selecting DataTemplate for WPF ListView - Way 2

In continuation to my previous article titled 'Dynamically selecting DataTemplate for WPF ListView', in this article, I am discussing about the alternative way to achieve the same goal. But here, to make the example simple, I am going to display only Employee names as shown below:













Now this to achieve this, I am going to inherit MarkupExtension class provided by Microsoft. This class will give me the DataTemplate. If you will explore further, you will came to know that this MarkupExtension class has only one method named as ProvideValue, which will return me the appropriate template based on the supplied value. 

Before inheriting MarkupExtension, I created a class named MyDataTemplateDictionary, which will inherit Dictionary<object, DataTemplate>. Please note, here key will be my DataTemplate name and value will be the DataTemplate. Below is the code depicting the same:








Next comes is the class inheriting MarkupExtension. As there is nothing much to explain in this code, I'm directly showing it:















And finally the class inheriting DataTemplateSelector, which is exactly the same code as shown in previous post:














And last but not the least, our XAML:















And we are done. Isn't it the cleaner approach???

Tuesday, January 21, 2014

Dynamically selecting DataTemplate for WPF ListView - Way 1

Recently I get a chance to work on a project in which requirement was to select different different types of data templates based on the data. I faced bit difficulty, but afterwards I was manage to get it work.

Let's have a look at the scenario first: Inside a WPF ListView, there are two GridViewColumns for storing Name and Age. Now requirement is to highlight the name of the person based on certain age criteria. If age is below 25, then name should be highlighted as red else it should be in green color, with desired background. I know there are ways to implement this using the concept of triggers, but I personally refrain from using triggers due to performance fall back.

So, what else ???

The option left was dynamically selecting data templates. In this post I am going to write about the simplest approach and later on I'll do the same thing using Dictionary. Well, let's begin with our code.

First of all, I created a class named Employee and added some data which will be displayed on UI. Code to perform this is as:














Next thing, I did is, defined the two DataTemplate in XAML as:







Once the data templates are defined, next task is to figure out the way on how to select the data templates dynamically. So, to perform this task, Microsoft provide us with the class called DataTemplateSelector.  Using this class, one can select the data templates based on the business requirement and here is the code:














Next task is to bind this newly created class named MyTemplateSelector with out XAML. So, in order to perform this task, I created a ResourceDictionary and kept both the data templates inside it as:










Till here we are almost done. The only thing pending is binding our ListView control to collection and setting the cell template, which can be done as:










Once everything is in place, we will get the desired output:











All the above thing can be done by inheriting MarkupExtension class also. I covered that in my next post here.

Sunday, January 12, 2014

Better way to play sound file on WPF button click

Recently I was working on a XAML based application, in which my requirement was to play a sound (.wav file) whenever a given button is clicked. So, to achieve this, I wrote a below snippet:










My above snippet worked but at the same time, I feel a noticeable delay in beep sound and that make me analyze further and write a blog post :)

Now question is, why there is delay between button click and sound ???
Well, there is a simple concept behind it, which I missed while implementing above requirement :(

Reason is, the event hierarchy. 

Most of us might be aware that Click is a bubbling event, which means event will be fired from the control who initiated it. So, in our case, whenever button is clicked, it bubbles from button to window. And that's the reason, click event handler is executing before the window event is triggered, which is ultimately leading to delay.

Now, how to handle this???

Method 1:
Then I thought to write a preview event, which will be fired before my button click and came out with this below code:











In the above snippet, I am using VisualTreeHelper to verify is click event is occurred on button or not. Don't you think, it is bit dreadful? If it seems good, then you can go ahead with this approach else I got one more idea to implement this using ResourceDictionary.

Method 2:
Let's use Styles and EventSetter to achieve the same goal. Here I am going to define my style in a ResourceDictionary, now of course I don't have instance that I could wire my event to. For this, I created a code-behind file for ResourceDictionary, which will appear as a child of my XAML file and will contain the below code:












Now only thing pending is merging the ResourceDictionary with our MainWindow, which can be done as:










For me, this approach looks better. Hope you enjoyed reading!!!

Saturday, January 4, 2014

DataTemplating Overview

DataTemplate is a very powerful concept which allows you to provide a visualization for your objects in your application. DataTemplate objects are very useful specially dealing with collections. If you bind your collection with any of the ItemsControl, say ListBox then by using a DateTemplate one can change the appearance of data objects very easily. Well, now let's create a DataTemplate quickly.

Let's start by creating a class called Employee:








FirstName and Age will be our business objects that will reside in our application. Now we will go ahead and show the value of these objects on screen in a WPF application. For that our XAML will look like:








Now looking at the code-behind:










In code-behind, we have set the values for FirstName and Age with DataContext of main window. So, that XAML can bind to these values via EmployeeDetail property. At this point of time, if you will run the application, you will see:














By above image you can see that the default implementation of DataTemplate in WPF has simply put the string on my window, where TemplatingOverview is my namespace. So, to make it work in order to show proper values, let's go ahead and override ToString on Employee object, something like this:










In above snippet we are saying that please provide us the string with given format. Now, if you will go ahead and run this again you will find that our DataTemplate is changed and now it is using our overriden ToString.















Till here, I showed that what will happen if you will not provide your own DataTemplate. Now instead of writing overriden method, same thing can be performed fully in XAML as:












In above snippet, we have created a DataTemplate on the ContentControl and inside this DataTemplate, one can do any styling and can create any number of visual elements. Later on, these visual elements can be bind to any public property of Employee object. Please note, the Datacontext for this DataTemplate will be EmployeeDetail. Now, if you will run the app, still you can see the value of Employee object.

Sharing DataTemplate
Now in order to share this DataTemplate between multiple ContentControls, one has to make this as a part of resource. Let's have a look at the complete code to get clear idea:













Hope you enjoyed reading. In Next article, I'll be writing about DataTemplateSelector.

Thursday, January 2, 2014

Validating a WPF textbox to accept only negative decimal numbers

Recently working on one of the project, I came across an requirement of validating a TextBox in which Textbox should allow numbers only between range -999 and 0.

If you will surf on internet, you will perhaps find many solutions to this problem in which developers create their own versions of TextBox either by creating a Custom/User controls or by inheriting it. But problem of this approach is - you would need to replace your TextBox definitions with your newly created TextBox. Sometimes this solution can be opted but sometimes it is not feasible to do so.

This article describes on how to enhance existing WPF TextBox to make it happen.So, the approach I am proposing here doesn't require the replacement of existing TextBox control. Whilst it uses the very basic concept of Events. Well, enough of theory. Let's move on to coding part:

XAML code:






Code-Behind code:

Hope you like this clean approach.

Wednesday, January 1, 2014

Troubleshooting data binding

We all know that DataBinding is one of the most powerful concept of WPF. So, today I thought to write something on how to troubleshoot data binding related issues while working with any XAML based application. Here I'll not talk about what and how data binding works, instead I'll jump directly on the relevant part. So, let's start by picking up the troubleshooting methods which can make developer's work bit easy.

Way 1: Using Visual Studio output window
Visual Studio provides high level information about binding which is sufficient to resolve very small problems like name mismatch, etc. Let's understand this along with a code snippet:
 <Grid>
        <TextBlock Text="{Binding  ElementName=label, Path=Hello, Mode=OneWay}"/>
        <Label Content="Welcome" Name="label"/>
  </Grid> 
Now open your output window and press F5, application will launch. In output window, you will notice that the message stating: 

System.Windows.Data Error: 40 : BindingExpression path error: 'Hello' property not found on 'object' ''Label' (Name='label')'. BindingExpression:Path=Hello; DataItem='Label' (Name='label'); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') 

After reading the above message, it is very easy to identify and resolve the issue. Isn't it ??? 

Way 2: Using TraceLevel
TraceLevel is an AttachedProperty which was introduced with .Net 3.5. This adds the trace information to the output window of Visual Studio with detail level of None, Medium or High. To use this TraceLevel property, one extra namespace needs to be incorporate in XAML as:   
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase" 
and add the TraceLevel to the binding as: 
<Grid>
    <TextBlock Text="{Binding  ElementName=label, Path=Hello, Mode=OneWay,diag:PresentationTraceSources.TraceLevel=High}"/>
        <Label Content="Welcome" Name="label"/>
</Grid> 

Way 3: Using Snoop
Snoop is the WPF utility which allows you to browse through the visual tree of a running WPF application. More details about snoop can be found here

Way 4: Debugging data binding using an converter
One can write a converter and put a breakpoint inside the convert method. Once this is done, the converter need to be setup in the binding. Let's have a look at the code: 

 namespace DebuggingDataBinding
{
    /// <summary>
    /// Converter to debug the binding values
    /// </summary>
    public class DebugConvertor : IValueConverter
    {
        #region IValueConverter Members

        /// <summary>
        /// ask the debugger to break
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Debugger.Break();
            return Binding.DoNothing;
        }

        /// <summary>
        /// ask the debugger to break
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Debugger.Break();
            return Binding.DoNothing;
        }

        #endregion
    }

    /// <summary>
    /// Markup extension to debug databinding
    /// </summary>
    public class DebugBindingExtension : MarkupExtension
    {
        /// <summary>
        /// Creates a new instance of the Convertor for debugging
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <returns>Return a convertor that can be debugged to see the values for the binding</returns>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return new DebugConvertor();
        }
    }
} 
In above snippet, provide value will create an instance of converter and return it. Now the XAML binding to sue this extension will be as:
<Window x:Class="DebuggingDataBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:DebuggingDataBinding"
    Title="Window1" Height="300" Width="300">
        <Grid Height="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Height, Converter={local:DebugBinding}}"/>
 </Window> 

Way 5: Using ExceptionValidationRule
One can associate ValidationRules with binding objects. So, whenever exception is thrown while updating binding source property, ExceptionValidationRule class will take care of it based on how we specify our logic to react with these exceptions. Let's have a look at the code.

I have a class named Person as:
public class Person
    {
        private string firstname;
        public string Firstame
        {
            get { return this.firstname; }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    throw new Exception("First name cannot be null or empty");
                }
                this.firstname = value;
            }
        }
    } 
Now we need to associate a rule with the binding and that can be done using in-built class calledExceptionValidationRule and XAML code will be:   
<TextBox Height="30" Width="80">
    <TextBox.Text>
        <Binding Path="FirstName" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <ExceptionValidationRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox> 
Please note, once can always come up with their own validation rules. 

Bit on performance
  • Less converters can lead to good performance - If possible, use minimal converters because converters require boxing and unboxing. One alternative is to create a property in a ViewModel, do conversion related activity in getter and bind to it.
  • Binding.DoNothing -  This seems to be useful in the scenario where return value of a converter need not to interfere in the binding process. In such cases, FallbackValue can be used.
  • Data binding cheatsheet can be found here

Friday, December 20, 2013

Automatic Numbering for the Primary Key Column

Many of you might have come across an issue of Auto incrementing while working with database products. Truly speaking, recently I also came across one silly problem and thought of sharing it here.
Imagine that at some point of time, you might want to send your new data to a back-end database. If your application supplies the auto-increment values, then
  • what will the database do?
  • what if application receives duplicate values from different client applications?
The answer is that these auto-increment values are never sent to the database because the auto-increment column in the database table will provide a value whenever a new row is added. After each new row is added, the back-end database table generates a new-increment number and then your application will query the database to get the newly created number. Your application will then update its primary key number to the values that came from the database. This means that all the foreign key references will need to be updated as well.

Another problem, what happens if you add new rows in your application to generate auto-increment values of 1 to 100 and then send these rows back to the database table, and the table already has 10 rows???

When the first row is sent from your application, it has an auto-increment value of 1. The new auto-increment number created in the database will be 11. Your application queries for the 11 and tries to change the 1 to 11. Guess, what will happen here? Of course, an EXCEPTION will be thrown because 11 is already in your table.

The solution to this problem is, set AutoIncrementSeed to -1 and set AutoIncrementStep to -1. This will cause negative numbers to be generated; they won't conflict with the values coming from the database because the database doesn't generate negative numbers.

Hope the above small tip will save your lot of time in debugging the code to find the root cause. Enjoy learning !!! 

Saturday, December 14, 2013

Formatting strings in binding

Recently I get a chance for a code walk through of an WPF application in order to achieve better performance. So, during my review process, I came across this below code snippet:

  <WrapPanel>
        <TextBlock Text="{Binding Path=FirstName,Mode=OneWay}"/>
        <TextBlock Text=" "/>
        <TextBlock Text="{Binding Path=LastName,Mode=OneWay}"/>
    </WrapPanel>

If you will closely analyze this given snippet, you will definitely get a way to optimize it. Well, I am talking  about formatting the string as well as binding part.

As most of you are aware that we have a property named StringFormat since .Net 3.5 SP1. So, why can't we use this StringFormat for our binding too. If you want to change the above code to incorporate StringFormat, then it will something look like:

<WrapPanel>
        <TextBlock>
                <TextBlock.Text>
                    <MultiBinding StringFormat="{}{0} {1}">
                        <Binding Path="FirstName" Mode="OneWay"/>
                        <Binding Path="LastName" Mode="OneWay"/>
                    </MultiBinding>
                </TextBlock.Text>
        </TextBlock>
    </WrapPanel>

Now here one can clearly see the double benefit of writing such code. First benefit is, instead of using two bindings, one can be used and another benefit is instead of using three TextBlocks only one TextBlock can be used.

This may help in achieving performance especially when used as a DataTemplate of an ItemsControl with huge number of items.

Please note that {} part at the beginning is an escape sequence, otherwise XAML parser would consider { to be the beginning of markup extension.

Tuesday, December 10, 2013

Resizing TextBlock with resizing of window

When dealing with XAML, many of you might have came across resizing issues in which your control is getting resize but the text/image inside the control is not getting resize as per the window size(it can be other user control). So, to deal with this Microsoft provide us with a Viewbox control, in which user can set the resizing aspects as per the need and requirement. So, this article focuses mainly on the properties provided by Viewbox control with proper sample code and output. MORE...

Thursday, November 14, 2013

Safest way to use RaisePropertyChanged method - MVVM series 3 of n

Background

In my previous post on Simplest MVVM Ever, I gave the simplest overview of implementing MVVM. Now moving forward, I thought to extend my previous post by picking individual areas. And this time, I selected RaisePropertyChanged. All the developers working on XAML related apps are very well aware about the use of this RaisePropertyChanged. I am sure, most of us are also aware on where to use this. But does everyone aware about what is the proper way or let's say generic way to use it ??? Well, even if you are not aware, no problem. At the end of this post, you will surely take home a useful tip on using RaisePropertyChanged.

Introduction

As we know that MVVM provides a loose coupling methodology. At lot many places it is very useful to get benefit of such architecture, but at the cost of your alertness. Because when we are talking about MVVM, we usually says that ViewModel has no knowledge about View and properties are the way, who binds View and ViewModel to show the data on the UI. Here is the gotcha !!!
ViewModels implement INotifyPropertyChanged interface, so that the property changes in ViewModel can be passed onto View. Let's take a sample property, to understand in better way:
public string SelectedName
{
    get { return _selectedName; }
    set
    {
        if (_selectedName != value)
        {
            _selectedName = value;
            RaisePropertyChanged("SelectedName");
        }
    }
}
Point to note here is the hard coded name of the property "SelectedName" within the RaisePropertyChangedmethod. Now due to requirement change, one of the developer came and change the name of a property fromSelectedName to FirstName, and at the same time, he forgot to change the parameter of  RaisePropertyChanged method.  Now what will happen ???
This silly oversight will neither cause any compilation or run time errors, but our feature will simply not work. And such things are very difficult to detect until and unless there is a major break in functionality. So, now, how to get rid of such sort of issues???  

Tip comes here  

Instead of hard coding the property name, can't we go ahead and fetch the property name dynamically using Reflection APIs. Well, of course we can. 
Reflection.MethodBase.GetCurrentMethod().Name 
To implement it in better way, let's go ahead and create an extension method to read this property name as:
 public static string GetPropertyName(this System.Reflection.MethodBase methodBase)
{
    return methodBase.Name.Substring(4);
}
Here Substring method is required to get rid of 'get_' and 'set_' at the start depending upon where it is called. 
So, by using this extension method, one will be able to raise property changed events without concern that in future your property name might change.  MORE