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

Advertisement

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.