Copy constructor does exist in C++, but not in C#. There is a great artilce by John Conners dedicated to this issue. It helped me to solve my issue, when i was working on implemention of IEditableObject interface in my ViewModel. Here is the issue. Interface IEditableObject suppose that you will create internal copy of object’s data, while it being edited. If edit operation was canceled, you should restore state of you object. Quite simple. ViewModel always implements INotifyPropertyChanged to notify View about changes. In order to restore View’s state you need to refresh ViewModel properties, not replace internal object. This leads to ugly code, like this:


        public override void CancelEdit()
        {
            if (IsEditing)
            {
                Name = InternalCopy.Name;
                Address= InternalCopy.Address;
                SSN= InternalCopy.SSN;
                //and so on...
                IsEditing = false;
            }
        }

Public Overloads Overrides Sub CancelEdit()
    If IsEditing Then
        Name = InternalCopy.Name
        Address = InternalCopy.Address
        SSN = InternalCopy.SSN
        'and so on...
        IsEditing = False
    End If
End Sub

You can end up with a bunch of properties being copied, but that is not the worst. New properties will not be copied automatically, so you will have tricky bugs in your app. Definitely a solution is needed. It is pretty obvious. I have created class with extension method, which copies all properties using reflection from one instance to another. It perfectly addresses the issue.


    public static class ObjectCopier
    {
        public static void CopyFields<T>(this T dest, T source)
        {
           PropertyInfo[] properties = dest.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

           foreach (PropertyInfo propertyInfo in properties)
            {
                propertyInfo.SetValue(dest, propertyInfo.GetValue(source, null), null);
            }
        }
    }

Public Module ObjectCopier

    <System.Runtime.CompilerServices.Extension()> _
    Public Sub CopyFields(Of T)(ByVal dest As T, ByVal source As T)
        Dim properties As PropertyInfo() = dest.[GetType]().GetProperties(BindingFlags.[Public] Or BindingFlags.Instance)

        For Each propertyInfo As PropertyInfo In properties
            propertyInfo.SetValue(dest, propertyInfo.GetValue(source, Nothing), Nothing)
        Next
    End Sub

End Module

Look, how clear and cool it became.


        public override void CancelEdit()
        {
            if (IsEditing)
            {
                this.CopyFields(InternalCopy);
                IsEditing = false;
            }
        }

Public Overloads Overrides Sub CancelEdit()
    If IsEditing Then
        Me.CopyFields(InternalCopy)
        IsEditing = False
    End If
End Sub

When DataGrid was introduced  into WPF, I was happy. I really lack this control. As many other developers I found one drawback of new control. When you use DataGridTemplateColumn, it doesn’t set focus automatically on control inside DataGridTemplateColumn.CellEditingTemplate. This requires from you to click 3 times to edit the cell or press tab twice. It is very annoying. Discussion of this bug and possible solutions was made at code plex http://www.codeplex.com/Thread/View.aspx?ProjectName=wpf&ThreadId=35540 . I found my own solution. When you start to edit cell, wpf creates controls for data edit, like textboxes. So we need to transfer focus to them immediately. I created attacher class:

public class FocusAttacher
    {

        public static readonly DependencyProperty FocusProperty = DependencyProperty.RegisterAttached(&amp;quot;Focus&amp;quot;, typeof(bool), typeof(FocusAttacher), new PropertyMetadata(false, FocusChanged));

        public static bool GetFocus(DependencyObject d)
        {
            return (bool)d.GetValue(FocusProperty);
        }

        public static void SetFocus(DependencyObject d, bool value)
        {
            d.SetValue(FocusProperty, value);
        }

        private static void FocusChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                ((UIElement)sender).Focus();
            }
        }

    }
Public Class FocusAttacher

Public Shared ReadOnly FocusProperty As DependencyProperty = DependencyProperty.RegisterAttached(“Focus”, GetType(Boolean), GetType(FocusAttacher), New PropertyMetadata(False, New PropertyChangedCallback(AddressOf FocusChanged)))

    Public Shared Function GetFocus(ByVal d As DependencyObject) As Boolean
        Return CBool(d.GetValue(FocusProperty))
    End Function

    Public Shared Sub SetFocus(ByVal d As DependencyObject, ByVal value As Boolean)
        d.SetValue(FocusProperty, value)
    End Sub

    Private Shared Sub FocusChanged(ByVal sender As Object, ByVal e As DependencyPropertyChangedEventArgs)
        If CBool(e.NewValue) Then
            DirectCast(sender, UIElement).Focus()
        End If
    End Sub

End Class

As you can see, this class can be attached to any UIElement and calls focus immediately.
You can use it like this:

        &amp;lt;tk:DataGrid CanUserAddRows=&amp;quot;True&amp;quot; ItemsSource=&amp;quot;{Binding}&amp;quot; AutoGenerateColumns=&amp;quot;False&amp;quot;&amp;gt;
            &amp;lt;tk:DataGrid.Columns&amp;gt;
                &amp;lt;tk:DataGridTemplateColumn Header=&amp;quot;Name&amp;quot;&amp;gt;
                    &amp;lt;tk:DataGridTemplateColumn.CellTemplate&amp;gt;
                        &amp;lt;DataTemplate&amp;gt;
                            &amp;lt;TextBlock Padding=&amp;quot;3&amp;quot; Text=&amp;quot;{Binding Name}&amp;quot; /&amp;gt;
                        &amp;lt;/DataTemplate&amp;gt;
                    &amp;lt;/tk:DataGridTemplateColumn.CellTemplate&amp;gt;
                    &amp;lt;tk:DataGridTemplateColumn.CellEditingTemplate&amp;gt;
                        &amp;lt;DataTemplate&amp;gt;
                            &amp;lt;TextBox Text=&amp;quot;{Binding Path=Name, Mode=OneWay}&amp;quot; lc:FocusAttacher.Focus=&amp;quot;True&amp;quot; /&amp;gt;
                        &amp;lt;/DataTemplate&amp;gt;
                    &amp;lt;/tk:DataGridTemplateColumn.CellEditingTemplate&amp;gt;
                &amp;lt;/tk:DataGridTemplateColumn&amp;gt;
                &amp;lt;tk:DataGridTemplateColumn Header=&amp;quot;Phone&amp;quot;&amp;gt;
                    &amp;lt;tk:DataGridTemplateColumn.CellTemplate&amp;gt;
                        &amp;lt;DataTemplate&amp;gt;
                            &amp;lt;TextBlock Text=&amp;quot;{Binding Path=Phone}&amp;quot; Padding=&amp;quot;3&amp;quot;/&amp;gt;
                        &amp;lt;/DataTemplate&amp;gt;
                    &amp;lt;/tk:DataGridTemplateColumn.CellTemplate&amp;gt;
                    &amp;lt;tk:DataGridTemplateColumn.CellEditingTemplate&amp;gt;
                        &amp;lt;DataTemplate&amp;gt;
                            &amp;lt;TextBox Text=&amp;quot;{Binding Path=Phone, Mode=OneWay}&amp;quot; lc:FocusAttacher.Focus=&amp;quot;True&amp;quot; /&amp;gt;
                        &amp;lt;/DataTemplate&amp;gt;
                    &amp;lt;/tk:DataGridTemplateColumn.CellEditingTemplate&amp;gt;
                &amp;lt;/tk:DataGridTemplateColumn&amp;gt;
                &amp;lt;tk:DataGridTemplateColumn Header=&amp;quot;Address&amp;quot;&amp;gt;
                    &amp;lt;tk:DataGridTemplateColumn.CellTemplate&amp;gt;
                        &amp;lt;DataTemplate&amp;gt;
                            &amp;lt;TextBlock Text=&amp;quot;{Binding Path=Address}&amp;quot; Padding=&amp;quot;3&amp;quot;/&amp;gt;
                        &amp;lt;/DataTemplate&amp;gt;
                    &amp;lt;/tk:DataGridTemplateColumn.CellTemplate&amp;gt;
                    &amp;lt;tk:DataGridTemplateColumn.CellEditingTemplate&amp;gt;
                        &amp;lt;DataTemplate&amp;gt;
                            &amp;lt;TextBox Text=&amp;quot;{Binding Path=Address, Mode=OneWay}&amp;quot; lc:FocusAttacher.Focus=&amp;quot;True&amp;quot; /&amp;gt;
                        &amp;lt;/DataTemplate&amp;gt;
                    &amp;lt;/tk:DataGridTemplateColumn.CellEditingTemplate&amp;gt;
                &amp;lt;/tk:DataGridTemplateColumn&amp;gt;
            &amp;lt;/tk:DataGrid.Columns&amp;gt;
        &amp;lt;/tk:DataGrid&amp;gt;

This completely solves the problem, when you start to edit cell, focus immediately goes to required control.

Sample projects which show such datagrid and attacher class in action is available .

Change Property Command

February 11, 2009

Many applications requires history support (undo/redo). I found class ChangPropertyCommand very helpful for such tasks, because it allows you to specify any property of the object to be changed, so you don’t need to write many classes.

public class ChangePropertyCommand : Command
{

    private var Target_;
    private var NewValue_;
    private var OldValue_;
    private string PropertyName_;
    public ChangePropertyCommand(object Target, string PropertyName, object Value)
    {
        Target_ = Target;
        NewValue_ = Value;
        PropertyName_ = PropertyName;
        OldValue_ = GetValue();
    }

    public override void Execute()
    {
        base.Execute();
        SetValue(NewValue_);
    }

    public override void UnExecute()
    {
        base.UnExecute();
        SetValue(OldValue_);
    }

    private void SetValue(object Value)
    {
        object tmp = Target_;
        var type = Target_.GetType();
        string[] paths = PropertyName_.Split(".");
        PropertyInfo prop = type.GetProperty(paths(0));
        for (int i = 0; i <= paths.Length - 2; i++) {
            prop = type.GetProperty(paths(i));
            tmp = prop.GetValue(tmp, null);
            type = tmp.GetType;
        }
        prop = type.GetProperty(paths(paths.Length - 1));
        prop.SetValue(tmp, Value, null);
    }

    private object GetValue()
    {
        object ret = Target_;
        var type = Target_.GetType();
        string[] paths = PropertyName_.Split(".");
        foreach (string path in paths) {
            var prop = type.GetProperty(path);
            ret = prop.GetValue(ret, null);
            if (ret != null) {
                type = ret.GetType;
            }
        }
        return ret;
    }
}

Imports System.Reflection

Public Class ChangePropertyCommand
Inherits Command

Private Target_
Private NewValue_
Private OldValue_
Private PropertyName_ As String
Sub New(ByVal Target As Object, ByVal PropertyName As String, ByVal Value As Object)
Target_ = Target
NewValue_ = Value
PropertyName_ = PropertyName
OldValue_ = GetValue()
End Sub

Public Overrides Sub Execute()
MyBase.Execute()
SetValue(NewValue_)
End Sub

Public Overrides Sub UnExecute()
MyBase.UnExecute()
SetValue(OldValue_)
End Sub

Private Sub SetValue(ByVal Value As Object)
Dim tmp As Object = Target_
Dim type = Target_.GetType()
Dim paths As String() = PropertyName_.Split(".")
Dim prop As PropertyInfo = type.GetProperty(paths(0))
For i As Integer = 0 To paths.Length – 2
prop = type.GetProperty(paths(i))
tmp = prop.GetValue(tmp, Nothing)
type = tmp.GetType
Next
prop = type.GetProperty(paths(paths.Length – 1))
prop.SetValue(tmp, Value, Nothing)
End Sub

Private Function GetValue() As Object
Dim ret As Object = Target_
Dim type = Target_.GetType()
Dim paths As String() = PropertyName_.Split(".")
For Each path As String In paths
Dim prop = type.GetProperty(path)
ret = prop.GetValue(ret, Nothing)
If ret IsNot Nothing Then
type = ret.GetType
End If
Next
Return ret
End Function

End Class

Here some example of using this class:

    ChangePropertyCommand width = new ChangePropertyCommand(CurrentElement, "Width", Current.Width);
    ChangePropertyCommand height = new ChangePropertyCommand(CurrentElement, "Height", Current.Height);

Dim width As New ChangePropertyCommand(CurrentElement, "Width", Current.Width)
Dim height As New ChangePropertyCommand(CurrentElement, "Height", Current.Height)

As you can see, this code creates two commands, they will change properties Width and Height of the CurrentElement object, by values from Current object.
Often, Execute and Unexecute methods are not called directly, but called by History class.

GreyableTextBlock

November 27, 2008

WPF naturaly doesn’t have image class, which supports Disable state. Alex P solved this problem. Label class support disable state, but TextBlock don’t. Sometimes you need to use TextBlock, not Label. So, here a little class GreyableTextBlock which addresed to this issue:

    public class GreyableTextBlock: TextBlock
    {
        static GreyableTextBlock()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(GreyableTextBlock), new FrameworkPropertyMetadata(typeof(GreyableTextBlock)));
            GreyableTextBlock.IsEnabledProperty.OverrideMetadata(typeof(GreyableTextBlock), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnIsEnabledChanged)));
        }

        private Brush ForegroundBrush;
        private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GreyableTextBlock text = (GreyableTextBlock)d;
            if (e.Property.Name.Equals("IsEnabled"))
            {
                if ((e.NewValue as bool?) == false)
                {
                    text.ForegroundBrush = text.Foreground;
                    text.Foreground = Brushes.Gray;
                }
                else if ((e.NewValue as bool?) == true)
                {
                    text.Foreground = text.ForegroundBrush;
                }
            }
        }
    }

Many people find chm format very useful and use html help workshop to create chm files. But it can be not very obvious how to add flash movies. Actually chm file is archive. If you change it extension to zip and open, you will see, something like this.

Chm Structure

Chm Structure

Let’s say, you have some html page and you want to insert flash movie at it. I assume, that you will have html markup similar to this:


But this will not work, because html help workshop will not add you flash movie (Some.swf) to chm file. You can check this using chm file as archive. It is reasonable question, why images are automatically added to chm files, but flash files are not? A suppose chm format wasn’t designed to display flash content.
So, we need to add flash content to chm file, but there is no way to specify for html help workshop which files should be added except htm files. But we know, that images, css and javascript files used in htm files are added automatically to resulted chm file. This leads to simple trick.

<img src="/Flash/Some.swf" style="visibility:hidden;" />

This will enforce html workshop help to add Some.swf to resulted chm file. Html help workshop doesn’t check extension of file, so you can add any desired content. Style “visibility:hidden” prevents image from displaying. That is all! Have fun!

Color Reduction in WPF

September 27, 2008

Sometimes we need to reduce colors in image by some reasons. WPF has built-in ability to reduce colors of the image. FormatConvertedBitmap class was design to perform such operations. Let’s take a look on the following code, which is part of demo available to download:

FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap();
newFormatedBitmapSource.BeginInit();
//Set source from image control
newFormatedBitmapSource.Source = iSource.Source as BitmapSource;

//Create palette of requied color. Pay heed to maxColorCount it can have any value, but PixelFormats supports only 2,4,16 and 256 colors.
BitmapPalette myPalette = new BitmapPalette(iSource.Source as BitmapSource, int.Parse(cbNumberOfColors.SelectionBoxItem as string));

newFormatedBitmapSource.DestinationPalette = myPalette;

//Set PixelFormats
newFormatedBitmapSource.DestinationFormat = PixelFormats.Indexed8;
newFormatedBitmapSource.EndInit();

iReduced.Source = newFormatedBitmapSource;

There are two important moments here. First,

//Create palette of requied color. Pay heed to maxColorCount it can have any value, but PixelFormats supports only 2,4,16 and 256 colors.
BitmapPalette myPalette = new BitmapPalette(iSource.Source as BitmapSource, int.Parse(cbNumberOfColors.SelectionBoxItem as string));

As you can see, we create Palette from source image. In the second parameter of the constructor we passing the desired number of colors. It creates palette with desired number of colors. Sweet. How does that works? I used reflector to find out. It uses IWICPalette_InitializeFromBitmap_Proxy function from windowscodecs.dll. This function has the following remark:

“The resulting palette contains the specified number of colors which best represent the colors present in the bitmap (according to the algorithm we use). The algorithm operates on the opaque RGB color value of each pixel in the reference bitmap and hence ignores any alpha values. If a transparent color is required, set the fAddTransparentColor parameter to TRUE and one fewer optimized color will be computed and a fully transparent color entry will be added.

This method is particularly useful with the error diffusion dithering algorithm described in the format conversion section.”

They don’t specify, which algorithm is used (  Official documentation has the following hint:

“They are intended to provide the best possible image quality with a reduced set of colors. Optimal palettes are generated from an image’s pixel values – usually using a histogram.”

So, we have palette now. Next, we need to assign indexes to all pixels from palette. If you take a look on the code, you probably didn’t find line, which suppose to assign indexes to pixels. I used to reflector to find out where it happens. Method FormatConvertedBitmap.EndInit calls virtual FinalizeCreation, which calls IWICFormatConverter_Initialize_Proxy from windowscodecs.dll. This function do the trick. It assigns indexes to pixels.

At the last part, I show you screen of the demo program and will give some comments.

Color reduction sample

Color reduction sample

This demo very simple. You can load image from hard disc to the left image box and convert it to the right image box by pressing “Convert” button. Save button allows you to save result on you hd. Combobox specifies desired number of colors.

You also can download whole VS2008 project in the zip archive. Change it’s extension, it is zip not pdf.

PS If somebody knows algorithms, which is used in windowscodecs.dll, please let me know, i will appreciate this.

WPF Clipboard Viewer

April 30, 2008

One of the common tasks is to monitor clipboard and perform some actions, when it changes. I encountered such task in WPF. WPF as well as .NET doesn’t have any built in components to solve this task. After some googling i found a great article, which describes how to monitor clipboard in windows form. I am strongly recommended to read this article, because further reading assumes, that you know it.

Why this approach is not possible in WPF? Because WPF Window doesn’t have property Handle and you can’t override WndProc. Seems to be troublesome. First problem can be solved using PresentationSource class. PresentationSource  is another wrapper around windows handle. You can get it using PresentationSource.FromVisual method. Actually, you will be working with HwndSource class, which is derived from PresentationSource. HwndSource has property Handle. So, first problem is solved. What about ovveriding WndProc? I don’t know how to do it in WPF, but i suggest another approach. HwndSource has method AddHook, which allows us to receive all window messages. Thanks to these ideas we can implement Clipboard Viewer in WPF. I called my class ClipBoardViewer, it construts from any HwndSource and expose event ClipBoardTextChanged. Feel free to modify it for your needs.

ClipBoardViewer.vb

Almost any developer encounter a task, where he need to make copyright string like that: ”© 2003—2008 Somecompany”. It is obviously, that you can manually code it annually. But there is more simple solution:

© 2003 — <%= DateTime.Now.Year> Somecompany

This code will produce result like ”© 2003—xxxx Somecompany”, where xxxx is the server’s year. Make sure, that server time is ok.

Introduction
The purpose of this article is to show how to write simple chat bot using C#. Bot will simply answer on any received messages, like that:
User: Hi
Skype Bot: User said: Hi
After that you can improve logic of your bot is much as needed, for example, i wrote bot, which helps me and my friends to play D&D ;) Your bot can use web services, databases or his own logic to provide assistance to user. Skype bots have great applied area. They can be pretty useful.

Library and Documentation

If you want to build skype bot you need Skype4COM.dll. It can be downloaded from developer zone of skype. Documentation also will be helpful.

“Skype4COM is an interface which represents the Skype API as objects, with properties, commands, and events and notifications. Use Skype4COM in any ActiveX environment, such as Visual Studio or Delphi, and use familiar scripting languages, such as Visual Basic, PHP, or Javascript. Skype4Com.dll is automatically included together with Skype Extras Manager during Skype installation. If a user has unchecked Extras Manager during installation, Skype4Com library will be unavailable on that machine.” — from developer zone. Obviously, C# is well suited for working with COM libraries and GUI. Documentation has visual basic script examples, but no examples on C#.

Creating C# Project and Adding Reference

Let’s start VS2005. Create C# project as Windows Application. I called it Simple Skype Chat Bot.

Create project “simple skype chat bot”

Now, we need to include Skype4COM.dll to our project. Just right-click “References” in Solution Explorer and select option “Add Reference” in popup menu. You will see four tabs in the “Add Reference” dialog box, choose COM tab. In the listbox choose Skype4COM 1.0 Type Library. You should have it, if you have Skype Extras Manager. If you don’t have it, then download it and register using regsvr32 command.

Add Reference Skype4COM

Press Ok. Now Skype4COM.dll is included to our project. VS2005 generate Runtime Callable Wrapper using TlbImp.exe. It will imports types definitions found in COM library into equivalent .NET types. If you want know more about .NET and COM interaction read “C#.NET and COM Interop” article by Ravi Sankar. You can view generated types in object explorer, select SKYPE4COMLib.

Object Browser Skype4COM 

Attaching to the Skype
SkypeClass is the main class for working with skype, we need to create it and attach to Skype. First, create a variable of this class in you from class. I prefer to make initialization of SkypeClass object atFrom_Load event, you can choose any other suitable for you.

Subscribing to Skyep events 

As you can see, variable skype of the class SkypeClass was declared. At the SkypeChatBotForm_Load event handler we check is skype running. If not we start the skype application. After that we subscibe on two events: AttachmentStatus and MessageStatus. Change of the user status fires AttachmentStatus event handler, there we attach to skype. Run the project. You will see Skype dialog. It will ask you about our application accessing skype. Say yes.

Attaching to skype 

Answering to the received messages
Our next goal is to handle receive messages in skype_MessageStatus event handler and answer to them. There are a lot of types of messages, but we have interest only in received messages. Enum TChatMessageStatus contains all possible values, so TChatMessageStatus.cmsReceived is the proper value for received message.

Answering messages 

pMessage is instance of ChatMessage class. Through it we can get access to our chat and answer using method SendMessage. pMessage.Body contains text of the received message and pMessage.FromDisplayName contains name of the person who sent message. That’s all. You can run your bot and chat with somebody. He will be surprised of your typing speed ;-)

Chating with bot 

As you can see, Aleksey said “Hi” to me and bot answered from my account.

Deployment

If you will decide to publish your bot, you should keep in mind, that not all users have Skype4COM.dll. Maybe you need to include it in your deployment package and register in user’s systems.

Conclusion

As you noticed, bot answered to received message by my name, not something like “Answering Bot”. It is because your application can attach only to working copy of skype. One of the most pity things: there is no way to run more than one copy of skype in a single PC. That mean if you want to create useful bot, which will work always and has his own name — you need to create skype account and run this account with this bot on separate PC or virtual machine. In any way it is very resource consuming. I am dreaming about COM component which will allows to use skype network without attaching to already running GUI. Something like Skype engine library. But it seems impossible due to commercial reasons, because then anybody will have possibility to write his own Skype client.

Thanks for assistance

  • Aleksey Shmatov
  • Tanya Koltunova

Download Source Code