Showing posts with label Debugging. Show all posts
Showing posts with label Debugging. Show all posts

Wednesday, March 12, 2014

Customizing debugging session - Part I

I hope, being a developer everyone needs to debug their code at least once a day even if it is a very small snippet. Frankly speaking, sometimes it becomes very frustrating when we are looking for a value of particular property or let’s say very few properties of a huge object and it gets TIMEOUT. Uhhh !!!

This time, we feel like there should be some easy way to navigate to that particular property instead of going to the object and clicking on plus symbol to reach the required property. Well, let’s understand it via code:

Aim: I have an Employee class with two members as EmployeeName and BranchName. I want to know the name and branch of an Employee during my debugging session. So, I start debugging and lend up on below screen:







Now in order to view the required details, I need to expand the employee object as shown in below screenshot:







Now first question is, is there any way to display customized message in debugger window? Answer would be YES. One simple override method will do this job for us.

Let’s go ahead and override the ToString method as shown below:












Now launch the application and you will be able to view your text during debugging as shown below:







Point to understand here is, by default Visual Studio uses ToString method in the debugger. Please note, overriding the method will only display the message and it won’t affect the values of your employee object. In other words, on click on plus symbol in debugger window, you will still be able to view employee’s branch and name.

Well, it’s time to move for next question which I feel is very important concept.
Second question is, is there any way to display value of required property instead of customized message? Again answer is a big YES. A simple attribute named DebuggerDisplay will rescue you.

Let’s quickly jump on the code to check, how to use this attribute:






As you can see that the attribute can be applied to class level and takes a string as a parameter and inside the string, one can reference the member variables of the class using curly braces. Now time to see, what debugger will show us:






Isn’t it a cool feature? Hope you will use it :)

One can use this DebuggerDisplay attribute with classes, enums, delegates, structs, fields, properties as well as with assemblies.

When to use this DebuggerDisplay attribute?
One certainly can’t use it all the time due to its maintenance overhead. I would recommend it to be used at class level and can be at properties level, if your properties are complex and less self-explanatory. Enjoy debugging!!!



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