Anonymous Types

Anonymous Types are one of the nice feature in .net framework and i have never seen this code snippet anywhere in my project. Anonymous Types enable you to create objects without writing a class definition for the data type. Instead, the compiler generates a class for you. The class has no usable name, inherits directly from Object, and contains the properties you specify in declaring the object. You create anonymous types by using the new operator together with an object initializer

Dim carID As Integer = 100
Dim carName As String = "Car Name"

Dim carValue = New With {Key carID, carName}

'Which is same as

Dim anotherCar = New With {Key .ID = carID, .Name = carName}
Console.WriteLine("CarID : {0}", anotherCar.ID)
Console.WriteLine("Car Name : {0}", anotherCar.Name)

Anonymous types contain one or more public read-only properties.You cannot declare a field, a property, an event, or the return type of a method as having an anonymous type. Similarly, you cannot declare a formal parameter of a method, property, constructor, or indexer as having an anonymous type.

Advertisement

.Net 4.5 ‘Delay’ Binding property

‘Delay’ is one of the coolest property which is introduced as a part of the series on WPF 4.5 new features.

As pointed out by MSDN, If you use a data binding to update a data source, you can use the Delay property to specify an amount of time to pass after the property changes on the target before the source updates. For example, suppose that you have a Slider that has its Value property data two-way bound to a property of a data object and the UpdateSourceTrigger property is set to PropertyChanged. In this example, when the user moves the Slider, the source updates for each pixel that the Slider moves. The source object typically needs the value of the slider only when the slider’s Value stops changing. To prevent updating the source too often, use Delay to specify that the source should not be updated until a certain amount of time elapses after the thumb stops moving.

<Window x:Class="WpfApplication6.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="166"
        Width="301">
    <Grid>
        <StackPanel>
            <Slider x:Name="ValueSlider"
                    Minimum="0"
                    Maximum="100"
                    Margin="20"
                    Height="25"
                    Value="{Binding ElementName=ValueText, Delay=500, Path=Text,Mode=TwoWay}" />
            <TextBox x:Name="ValueText"
                     Text="50"
                     Width="100"
                     Height="50"
                     FontSize="20"
                     HorizontalAlignment="Center" />
        </StackPanel>
    </Grid>
</Window>

Again, it’s a discrete addition to the WPF framework but it’s a useful one !

I Call it as “Sempu”

Using Sempu voice command makes it so you don’t have to play with mouse as much on your Visual Studio. Utilizing Sempu voice command is a great way to do stuff without mouse. Sempu is an updated version of  Shortcut List extension, which is now available as a free extension in Microsoft Visual Studio Gallery.

Features :

  • Integrated Speech Recognizer allows to execute commands through voice.
  • Fast and Fluid UI, integrated inside Visual  Studio IDE.

Download : http://visualstudiogallery.msdn.microsoft.com/f2964c90-68e2-4ddd-861a-bd66e5cd4434

Screenshot :

Sempu

Markup Extensions for events in .Net 4.5

My previous post was about how to create Custom Markup Extensions for XAML.  Until now, it was possible to use a markup extension in XAML to assign a value to a property, but couldn’t do the same to subscribe to an event. WPF 4.5 supports markup extensions for events. While WPF does not define a markup extension to be used for events, third parties are able to create a markup extension that can be used with events. When using the MVVM pattern, we often associates commands of the ViewModel with controls of the view, via binding mechanism. It has some drawbacks.Not all controls have Command property, and when exists, it corresponds to only one event of the control. The solution so far to this issue involved using the Interactivity assembly from the Expression Blend SDK. We can try something similar using the new feature, which will not require the Expression Blend SDK at all.

It is able to bind events directly to ViewModel methods, like this:

<Window x:Class="CustomMarkupForDateTime.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:custom="clr-namespace:CustomMarkupForDateTime"
        Title="MainWindow"
        Height="350"
        Width="525">
    <Grid>
        <Button Width="300"
                Height="30"
                Click="{custom:CommandBinder ShowWindowCommand}" />
    </Grid>
</Window>

With the ShowWindow method defined in the ViewModel

 public class ViewModel
    {
        public ICommand ShowWindowCommand { get; set; }

        public ViewModel()
        {
            ShowWindowCommand = new DelegateCommand(ShowWindow);
        }
        private void ShowWindow(object obj)
        {
            System.Windows.MessageBox.Show("Hello World!");
        }
    }

CommandBinder Markup Extension :

using System;
using System.Windows;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Markup;
using System.Reflection;

namespace CustomMarkupForDateTime
{
    public class CommandBinder : MarkupExtension
    {
        private string _commandPath;
        private ICommand _command;
        private Type _eventArgsType;

        public CommandBinder(string commandPath)
        {
            _commandPath = commandPath;
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            Delegate customDelegate = null;
            IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            if (target != null)
            {
                EventInfo eventInfo = target.TargetProperty as EventInfo;
                MethodInfo methodInfo = GetType().GetMethod("InvokeCommand", BindingFlags.NonPublic | BindingFlags.Instance);
                Type parameterType = null;
                if (eventInfo != null)
                    parameterType = eventInfo.EventHandlerType;

                if (parameterType != null)
                {
                    _eventArgsType = parameterType.GetMethod("Invoke").GetParameters()[1].ParameterType;
                    customDelegate = Delegate.CreateDelegate(parameterType, this, methodInfo);
                }
            }
            return customDelegate;
        }
        private void InvokeCommand(object sender, RoutedEventArgs e)
        {
            var dataContext = (sender as FrameworkElement).DataContext;
            if (_commandPath != null)
            {
                _command = (ICommand)ParseCommandPath(dataContext, _commandPath);
            }
            var cmdParams = Activator.CreateInstance(_eventArgsType);
            if (_command != null && _command.CanExecute(cmdParams))
                _command.Execute(cmdParams);
        }
        private Object ParseCommandPath(object target, string commandPath)
        {
            return target.GetType().GetProperty(commandPath).GetValue(target);
        }
    }
}

Custom Markup Extensions in XAML

A markup extension can be implemented to provide values for properties in an attribute usage, properties in a property element usage, or both. When used to provide an attribute value, the syntax that distinguishes a markup extension sequence to a XAML processor is the presence of the opening and closing curly braces ({ and }). The type of markup extension is then identified by the string token immediately following the opening curly brace.  When used in property element syntax, a markup extension is visually the same as any other element used to provide a property element value: a XAML element declaration that references the markup extension class as an element, enclosed within angle brackets (<>).  [msdn]

For both the general XAML language and WPF specific markup extensions, the behavior of each markup extension is identified to a XAML processor through a class called MarkupExtension (System.Windows.Markup), and provides an implementation of the ProvideValue method. This method on each extension provides the object that is returned when the markup extension is evaluated. The returned object is typically evaluated based on the various string tokens that are passed to the markup extension.

There’s not much ceremony to creating a markup extension.

using System;
using System.Windows;
using System.Windows.Markup;

namespace CustomMarkupForDateTime
{
    public class DateMarkup : MarkupExtension
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return DateTime.Now.ToShortDateString();
         }
    }
}

<Window x:Class="CustomMarkupForDateTime.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:custom="clr-namespace:CustomMarkupForDateTime"
        Title="MainWindow"
        Height="350"
        Width="525">
    <Grid>
        <TextBlock Text="{custom:DateMarkup}" />
    </Grid>
</Window>

Playing with the IserviceProvider

As the name suggest, it provides some services. Depending on the service you will call, you can have information about the types.  Here is the list of services provided.   Below example uses IProvideValueTarget service to get information about the target property name, type and the object owing that property.

using System;
using System.Windows;
using System.Windows.Markup;

namespace CustomMarkupForDateTime
{
    public class DateMarkup : MarkupExtension
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var service = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            string text = string.Format("Target Property Name : {1},{0} Type : {2}{0} Target Object Type : {3}",
                                        "\n", (service.TargetProperty as DependencyProperty).Name,
                                        (service.TargetProperty as DependencyProperty).PropertyType.Name,
                                        service.TargetObject.GetType().ToString());
            return text;
         }
    }
}

Markup Extension with Parameter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Threading.Tasks;
using System.Windows.Markup;
using System.Reflection;
using System.Threading;

namespace CustomMarkupForDateTime
{
    public class DateMarkup : MarkupExtension
    {
        private DependencyProperty _property;
        private DependencyObject _object;

        [ConstructorArgument("DateTimeFormat")]
        public string DateTimeFormat { get; set; }

        public DateMarkup() { }
        public DateMarkup(string dateFormat)
        {
            DateTimeFormat = dateFormat;
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var service = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            _property = service.TargetProperty as DependencyProperty;
            _object = service.TargetObject as DependencyObject;
            Timer _timer = new Timer(OnTimerCallback, this, 100, 100);            
            return DateTime.Now.ToString(DateTimeFormat);
        }
        private void OnTimerCallback(object state)
        {
            DateMarkup markup = (DateMarkup)state;
            if (!markup._object.Dispatcher.CheckAccess())
            {
                markup._object.Dispatcher.Invoke(() => markup._object.SetValue(_property, DateTime.Now.ToString(DateTimeFormat)));
            }
            else
            {
             markup._object.SetValue(_property, DateTime.Now.ToString(DateTimeFormat));
            }
        }
    }
}
<Window x:Class="CustomMarkupForDateTime.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:custom="clr-namespace:CustomMarkupForDateTime"
        Title="MainWindow"
        Height="350"
        Width="525">
    <Grid>
        <TextBlock Text="{custom:DateMarkup DateTimeFormat=dd/MMM/yyyy-hh:mm:ss}" />
    </Grid>
</Window>

Zipping Files and Folders using .Net

It has been almost a year since .NET 4.5 got released. But the problems with most of the recent Microsoft releases have been communication with .NET developers. Only one or two features are known to developers and other features just stay on MSDN and end up becoming simple documents.

For example, the time you ask a .NET developer what is new in the core framework .NET 4.5 most of them will just say async and await

Again it’s very difficult to run through all the new features. Because the features may not sound interesting depending on what you are working currently on..

So in this article I have picked a  nice feature introduced in .NET 4.5 core.

Zip File Creation

Now in .NET we did not have built-in support for implementing Zip compression. Many developers where using third party components like “DotnetZip”,”XceedZip”. In .NET 4.5, the Zip feature is baked in the framework itself, inside the namespace  System.IO.Compression

using System;
using System.Windows;
using System.IO.Compression;

namespace CompressionSample
{

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ZipButton_Click(object sender, RoutedEventArgs e)
        {
            ZipFile.CreateFromDirectory(@"F:\Pictures\Drawings",@"F:\Images.zip",CompressionLevel.Optimal,includeBaseDirectory:true);
        }
        private void UnzipButton_Click(object sender, RoutedEventArgs e)
        {
            ZipFile.ExtractToDirectory(@"F:\Images.zip",@"F:\Images");
        }
    }
}

The ZipFile class provides static methods for working with zip archives. To use these methods, you must reference the System.IO.Compression.FileSystem assembly in your project. The System.IO.Compression.FileSystem assembly is not available for windows store apps.