Convert RSA public/private key from XML to PEM format (.NET) (Part 2)

In my previous post I’ve shown how to convert the public key of an XML formatted RSA key to the more widely used PEM format. The only limitation of the solution was that since it utilizes the Cryptographic Next Generation (CNG) algorithms it is usable only on Windows 7 and Windows Server 2008 R2.

So bellow I’ll demonstrate a solution that works under all operating systems. Also as an extra the solution bellow can convert the private key as well 😉 Both the public and the private keys exported by the functions bellow are parsed by OpenSSL!

You can find the compiled source here.

Enjoy!

C#

private static byte[] RSA_OID = 
{ 0x30, 0xD, 0x6, 0x9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0xD, 0x1, 0x1, 0x1, 0x5, 0x0 }; // Object ID for RSA

// Corresponding ASN identification bytes
const byte INTEGER = 0x2;
const byte SEQUENCE = 0x30;
const byte BIT_STRING = 0x3;
const byte OCTET_STRING = 0x4;

private static string ConvertPublicKey(RSAParameters param)
{
    List<byte> arrBinaryPublicKey = new List<byte>();

    arrBinaryPublicKey.InsertRange(0, param.Exponent);
    arrBinaryPublicKey.Insert(0, (byte)arrBinaryPublicKey.Count);
    arrBinaryPublicKey.Insert(0, INTEGER);

    arrBinaryPublicKey.InsertRange(0, param.Modulus);
    AppendLength(ref arrBinaryPublicKey, param.Modulus.Length);
    arrBinaryPublicKey.Insert(0, INTEGER);

    AppendLength(ref arrBinaryPublicKey, arrBinaryPublicKey.Count);
    arrBinaryPublicKey.Insert(0, SEQUENCE);

    arrBinaryPublicKey.Insert(0, 0x0); // Add NULL value

    AppendLength(ref arrBinaryPublicKey, arrBinaryPublicKey.Count);

    arrBinaryPublicKey.Insert(0, BIT_STRING);
    arrBinaryPublicKey.InsertRange(0, RSA_OID);

    AppendLength(ref arrBinaryPublicKey, arrBinaryPublicKey.Count);

    arrBinaryPublicKey.Insert(0, SEQUENCE);

    return System.Convert.ToBase64String(arrBinaryPublicKey.ToArray());
}

private static string ConvertPrivateKey(RSAParameters param)
{
    List<byte> arrBinaryPrivateKey = new List<byte>();

    arrBinaryPrivateKey.InsertRange(0, param.InverseQ);
    AppendLength(ref arrBinaryPrivateKey, param.InverseQ.Length);
    arrBinaryPrivateKey.Insert(0, INTEGER);

    arrBinaryPrivateKey.InsertRange(0, param.DQ);
    AppendLength(ref arrBinaryPrivateKey, param.DQ.Length);
    arrBinaryPrivateKey.Insert(0, INTEGER);

    arrBinaryPrivateKey.InsertRange(0, param.DP);
    AppendLength(ref arrBinaryPrivateKey, param.DP.Length);
    arrBinaryPrivateKey.Insert(0, INTEGER);

    arrBinaryPrivateKey.InsertRange(0, param.Q);
    AppendLength(ref arrBinaryPrivateKey, param.Q.Length);
    arrBinaryPrivateKey.Insert(0, INTEGER);

    arrBinaryPrivateKey.InsertRange(0, param.P);
    AppendLength(ref arrBinaryPrivateKey, param.P.Length);
    arrBinaryPrivateKey.Insert(0, INTEGER);

    arrBinaryPrivateKey.InsertRange(0, param.D);
    AppendLength(ref arrBinaryPrivateKey, param.D.Length);
    arrBinaryPrivateKey.Insert(0, INTEGER);

    arrBinaryPrivateKey.InsertRange(0, param.Exponent);
    AppendLength(ref arrBinaryPrivateKey, param.Exponent.Length);
    arrBinaryPrivateKey.Insert(0, INTEGER);

    arrBinaryPrivateKey.InsertRange(0, param.Modulus);
    AppendLength(ref arrBinaryPrivateKey, param.Modulus.Length);
    arrBinaryPrivateKey.Insert(0, INTEGER);

    arrBinaryPrivateKey.Insert(0, 0x00);
    AppendLength(ref arrBinaryPrivateKey, 1);
    arrBinaryPrivateKey.Insert(0, INTEGER);

    AppendLength(ref arrBinaryPrivateKey, arrBinaryPrivateKey.Count);
    arrBinaryPrivateKey.Insert(0, SEQUENCE);

    return System.Convert.ToBase64String(arrBinaryPrivateKey.ToArray());
}

private static void AppendLength(ref List<byte> arrBinaryData, int nLen)
{
    if (nLen <= byte.MaxValue)
    {
        arrBinaryData.Insert(0, Convert.ToByte(nLen));
        arrBinaryData.Insert(0, 0x81); //This byte means that the length fits in one byte
    }
    else
    {
        arrBinaryData.Insert(0, Convert.ToByte(nLen % (byte.MaxValue + 1)));
        arrBinaryData.Insert(0, Convert.ToByte(nLen / (byte.MaxValue + 1)));
        arrBinaryData.Insert(0, 0x82); //This byte means that the length fits in two byte
    }

}

Convert RSA public key from XML to PEM format (.NET) (Part 1)

Probably the people working with asymmetric cryptography have struggled for a way to convert the XML format of the RSA public key to the more widely used PEM format. Although there is a solution for the reverse transformation (from PEM to XML) on the following address http://www.jensign.com/opensslkey/opensslkey.cs I have not found anywhere a solution to this problem.

So after a bit of reading and examining the code in the above mentioned link I’ve come up with a small code that does the conversion and the resulting key is parsed OK from OpenSSL.

NOTE: You will need to download and use the assemblies from http://clrsecurity.codeplex.com/
NOTE2: The code bellow only works under Windows 7 and Windows Server 2008 R2, because it uses the Cryptographic Next Generation (CNG) that were added only to those operating systems.

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            RSACng rsa = new RSACng();
            X509Certificate2 cert;
            List<byte> arrBinaryPublicKey = new List<byte>();

            byte[] oid = 
            { 0x30, 0xD, 0x6, 0x9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0xD, 0x1, 0x1, 0x1, 0x5, 0x0 }; // Object ID for RSA

            //rsa.FromXmlString(xmlFormatedRSAKey);

            cert = rsa.Key.CreateSelfSignedCertificate(new X500DistinguishedName("CN=something"));

            //Transform the public key to PEM Base64 Format
            arrBinaryPublicKey = cert.PublicKey.EncodedKeyValue.RawData.ToList();
            arrBinaryPublicKey.Insert(0, 0x0); // Add NULL value

            CalculateAndAppendLength(ref arrBinaryPublicKey);

            arrBinaryPublicKey.Insert(0, 0x3);
            arrBinaryPublicKey.InsertRange(0, oid);

            CalculateAndAppendLength(ref arrBinaryPublicKey);

            arrBinaryPublicKey.Insert(0, 0x30);
            //End Transformation

            Console.WriteLine();
            Console.WriteLine("-----BEGIN PUBLIC KEY-----");
            Console.WriteLine(System.Convert.ToBase64String(arrBinaryPublicKey.ToArray()));
            Console.WriteLine("-----END PUBLIC KEY-----");

        }

        private static void CalculateAndAppendLength(ref List<byte> arrBinaryData)
        {
            int nLen;
            nLen = arrBinaryData.Count;
            if (nLen <= byte.MaxValue)
            {
                arrBinaryData.Insert(0, Convert.ToByte(nLen));
                arrBinaryData.Insert(0, 0x81); //This byte means that the length fits in one byte
            }
            else
            {
                arrBinaryData.Insert(0, Convert.ToByte(nLen % (byte.MaxValue + 1)));
                arrBinaryData.Insert(0, Convert.ToByte(nLen / (byte.MaxValue + 1)));
                arrBinaryData.Insert(0, 0x82); //This byte means that the length fits in two byte
            }

        }

    }
}

Compiled source available here

Binding MaskedText property of Telerik Silverlight RadMaskedTextBox

If you have used Telerik’s RadMaskedTextBox for Silverlight most probably in some cases you have needed to bind in TwoWay mode the MaskedText property of the control (for example for Phones, SSNs, etc. that need to be saved with the punctuation). And most probably you were surprised that you cannot do this because the MaskedText property is readonly. We’ve asked Telerik whether they are considering to implement such a functionality, but currently there is no definite answer to this.

So here is how to extend they RadMaskedTextBox so you can do your work:

VB:

Imports System.Windows.Data
Imports Telerik.Windows

Public Class RadMaskedTextBoxExtended
    Inherits Telerik.Windows.Controls.RadMaskedTextBox

    Private m_bIsValueChangingIn As Boolean = False

#Region " Dependency Property "
    Public Shared ReadOnly ValueMaskProperty As DependencyProperty = _
    DependencyProperty.Register("ValueMask" _
                                , GetType(String) _
                                , GetType(RadMaskedTextBoxExtended) _
                                , New PropertyMetadata(AddressOf ValueMaskChanged) _
                                )
#End Region

#Region " Constructor "
    Public Sub New()
        MyBase.New()
        AddHandler Me.ValueChanged, AddressOf OnValueChanged
    End Sub
#End Region

#Region " Properties "
    Public Property ValueMask() As String
        Get
            Return CStr(Me.GetValue(ValueMaskProperty))
        End Get
        Set(ByVal value As String)
            Me.SetValue(ValueMaskProperty, value)
        End Set
    End Property

    Public Property IsValueChangingIn() As Boolean
        Get
            Return m_bIsValueChangingIn
        End Get
        Set(ByVal value As Boolean)
            m_bIsValueChangingIn = value
        End Set
    End Property
#End Region

#Region " Change Tracking Events "
    Private Sub OnValueChanged(ByVal sender As Object, ByVal e As RadRoutedEventArgs)
        m_bIsValueChangingIn = True
        Me.ValueMask = Me.MaskedText
        Dim oBindingExpression As BindingExpression = Me.GetBindingExpression(ValueMaskProperty)

        If oBindingExpression IsNot Nothing Then
            oBindingExpression.UpdateSource()
        End If
        m_bIsValueChangingIn = False
    End Sub

    Private Shared Sub ValueMaskChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
        Dim txtRadMaskedTextBoxExtended As RadMaskedTextBoxExtended = CType(d, RadMaskedTextBoxExtended)

        If Not Equals(e.OldValue, e.NewValue) _
        AndAlso Not txtRadMaskedTextBoxExtended.IsValueChangingIn _
        Then
            txtRadMaskedTextBoxExtended.Value = e.NewValue
        End If
    End Sub
#End Region

End Class

Then instead of using their control, just use RadMaskedTextBoxExtended and use the ValueMask property to bind the business object property that must contain the masked text.

This worked quite well in my case 🙂
Enjoy!

Simple Tile Horizontally / Tile Vertically functionality in WPF

Here is the main idea: We will have a grid with three rows and three columns. The middle column/row will be used to store the GridSplitter that will allow us to resize columns/rows once we are in one of the tile modes. So basically when we are in Tile Horizontally we will span the textboxes (the same can be doen with any other control) to take all the three columns. And if we are in Tile Vertically mode we will change the columns of the controls and will Span the controls so they take all the rows.
But enough talking, lets get to work:

XAML:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Width="3" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="3" />
        <RowDefinition/>
    </Grid.RowDefinitions>

    <TextBox x:Name="txtTextBoxTop"
             Grid.Row="0" Grid.Column="0"                
             Grid.ColumnSpan="3"
             />

    <GridSplitter x:Name="split"
                  Grid.Row="1" Grid.Column="0"
                  Grid.ColumnSpan="3"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  ResizeDirection="Rows"
                  />

    <TextBox x:Name="txtTextBoxBottom"
             Grid.Row="2" Grid.Column="0"                
             Grid.ColumnSpan="3"
             />
</Grid>

And here is the code that will change to one of the modes:

VB Code Behind:

Private Sub cmdTileHorizontally_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    Grid.SetColumn(txtTextBoxTop, 0)
    Grid.SetRow(txtTextBoxTop, 0)
    Grid.SetColumnSpan(txtTextBoxTop, 3)
    Grid.SetRowSpan(txtTextBoxTop, 1)

    Grid.SetColumn(split, 0)
    Grid.SetRow(split, 1)
    Grid.SetColumnSpan(split, 3)
    Grid.SetRowSpan(split, 1)
    split.ResizeDirection = GridResizeDirection.Rows

    Grid.SetColumn(txtTextBoxBottom, 0)
    Grid.SetRow(txtTextBoxBottom, 2)
    Grid.SetColumnSpan(txtTextBoxBottom, 3)
    Grid.SetRowSpan(txtTextBoxBottom, 1)
End Sub

Private Sub cmdTileVerically_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    Grid.SetColumn(txtTextBoxTop, 0)
    Grid.SetRow(txtTextBoxTop, 0)
    Grid.SetColumnSpan(txtTextBoxTop, 1)
    Grid.SetRowSpan(txtTextBoxTop, 3)

    Grid.SetColumn(split, 1)
    Grid.SetRow(split, 0)
    Grid.SetColumnSpan(split, 1)
    Grid.SetRowSpan(split, 3)
    split.ResizeDirection = GridResizeDirection.Columns

    Grid.SetColumn(txtTextBoxBottom, 2)
    Grid.SetRow(txtTextBoxBottom, 0)
    Grid.SetColumnSpan(txtTextBoxBottom, 1)
    Grid.SetRowSpan(txtTextBoxBottom, 3)
End Sub

It is simple as that! And as a bonus you even get resizing 🙂

Binding IsChecked property of RadioButton in WPF

If you have tried to bind the RadioButton’s IsChecked property in WPF to an object, you have most likely experienced the following problem: In OneWay bindings it works great. But if you have more than one RadioButtons binded TwoWay and you click on an unchecked one, you were expecting that the object to which the previously checked RadioButton was binded to receive the value of False. But you were wrong in your expectations. That’s because for some reasons Microsoft does not obey bindings and does not pass the False value to the DependencyProperty and instead of that they just assign the value False directly to the property, which ruins the binding.

There are many proposed solutions to this around the internet, problem with all those is that they do not work with dynamically generated controls. So since I had to find a way to make this working with dynamic controls, decided to make a wrapper of the real RadioButton which will correctly Bind in two ways. Here is the code for the wrapper:

using System;
using System.IO;
using System.Printing;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using Microsoft.Win32;

namespace Controls
{
    public class RadioButtonExtended : RadioButton
    {
        static bool m_bIsChanging = false;

        public RadioButtonExtended()
        {
            this.Checked += new RoutedEventHandler(RadioButtonExtended_Checked);
            this.Unchecked += new RoutedEventHandler(RadioButtonExtended_Unchecked);
        }

        void RadioButtonExtended_Unchecked(object sender, RoutedEventArgs e)
        {
            if (!m_bIsChanging)
                this.IsCheckedReal = false;
        }

        void RadioButtonExtended_Checked(object sender, RoutedEventArgs e)
        {
            if (!m_bIsChanging)
                this.IsCheckedReal = true;
        }

        public bool? IsCheckedReal
        {
            get { return (bool?)GetValue(IsCheckedRealProperty); }
            set
            {
                SetValue(IsCheckedRealProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for IsCheckedReal. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsCheckedRealProperty =
        DependencyProperty.Register("IsCheckedReal", typeof(bool?), typeof(RadioButtonExtended),
        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Journal |
        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
        IsCheckedRealChanged));

        public static void IsCheckedRealChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            m_bIsChanging = true;
            ((RadioButtonExtended)d).IsChecked = (bool)e.NewValue;
            m_bIsChanging = false;
        }
    }
}

So now all you have to do is to use the ExtendedRadioButton instead of the built-in one and bind to the IsCheckedReal property instead of the IsChecked one.
Enjoy 🙂

LINQ Mysteries: The Distinct Function

Recently I had to use the Distinct function introduced in LINQ. My surprise was that depending on where you put the Distinct clause you will receive different results.

Let us take the following example: Let dtAnswers be a DataTable that has two columns, named answer_value and answer_comment. What I was seeking as a result was to return the count of the different answer_value values from all the rows. So knowing how it is done in SQL, I’ve wrote the following LINQ query in code:

Dim nDifferentValues As Integer = _
(From answer in dtAnswers.Rows _
Distinct Select answer("answer_value").ToString()).Count()

My surprise was that this will return always the same thing, no matter what rows I have and what values I have in the answer_value column. So after struggling several hours I’ve decided to try the Function syntax of LINQ:

Dim nDifferentValues As Integer = _
(From answer in dtAnswers.Rows _
Select answer("answer_value").ToString()).Distinct.Count()

Now this returns results correctly.
My guess is that the first query computes distinct on the rows first (by reference) and after that from the result selects answer("answer_value").ToString(). While the second query first selects answer("answer_value").ToString() and after that computes distinct.
So be careful where you put you LINQ functions 😉

Having different CellEditor for different rows (Xceed WPF Grid)

Currently I needed to make an Xceed WPF Grid to have different CellEditors for one column for different rows based on a condition (in my case the condition was the content of the cell). I’ve found no info for a similar situation on Xceed’s Forums. I’ve tried using the CellContentTemplateSelector for that column but after some tests I’ve noticed that when user types in the cell for that column the template disappears. And this was unacceptable. After some brainstorming and with a small hint from Xceed Support I was able to make a solution. I’ll present it to you in this article.

This solution utilizes WPF DataTriggers. So if you are not very familiar with them please read the related articles on MSDN

CellEditor.xaml

<xcdg:CellEditor x:Key="CellEditorSelector">
    <xcdg:CellEditor.EditTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <TextBox x:Name="txtTextBox"
                        Visibility="Visible"
                        />
                <ComboBox x:Name="lstCombo"
                        Visibility="Collapsed"
                        />
                <CheckBox x:Name="chkCheckBox"
                        Visibility="Collapsed"
                        />
            </StackPanel>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}
                                                , Path=Content
                                                , Mode=OneWay}"
                                                Value="txt"
                >
                    <Setter TargetName="txtTextBox" Property="Visibility" Value="Visible"/>
                    <Setter TargetName="lstCombo" Property="Visibility" Value="Collapsed"/>
                    <Setter TargetName="chkCheckBox" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}
                                                , Path=Content
                                                , Mode=OneWay}"
                                                Value="lst"
                >
                    <Setter TargetName="txtTextBox" Property="Visibility" Value="Collapsed"/>
                    <Setter TargetName="lstCombo" Property="Visibility" Value="Visible"/>
                    <Setter TargetName="chkCheckBox" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}
                                                , Path=Content
                                                , Mode=OneWay}"
                                                Value="chk"
                >
                    <Setter TargetName="txtTextBox" Property="Visibility" Value="Collapsed"/>
                    <Setter TargetName="lstCombo" Property="Visibility" Value="Collapsed"/>
                    <Setter TargetName="chkCheckBox" Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>

By assigning the above given CellEditor to a column of and Xceed WPF Grid it will change the editor of the cell to a TextBox if the text in the cell is “txt”, to a ComboBox if the text in the cell is “lst” and to a CheckBox if the text in the cell is “chk”. By default the TextBox will be displayed.

This is a very simple example. I’ll leave to your imagination what else you can do with a similar CellEditor. You can have very complex conditions to choose which template to show. All you have to do is encapsulate the logic in a method and bind to the method in the DataTrigger. Binding property. <

Enjoy the Power WPF!

Passing DataSet to a WCF Method

Recently I’ve made a simple WCF service that had a method that takes a MemoryStream parameter. After some time I had to add another method that should take a whole DataSet as parameter. And then my problems begun!

After I’ve added the method and refreshed the service reference of my client the proxy class generator decided to create his own MemoryStream class in the namespace of my WCF service! Then I knew that the true evil of DataSets is back (for more informations see Scott Hanselmann’s post about using DataSets in web services). The solution – use the DataSet’s methods to get the data in XML format and pass the XML string instead of the DataSet itself to the service. Here is a sample code:

IService.vb:

<ServiceContract()> _
Public Interface IService
    <OperationContract()> _
    Function PassDataSet(ByVal sXMLSchema As String, ByVal sXML As String) As Boolean
End Interface

Note that because we do not know the schema of the DataSet in the service we also pass the XML schema of the DataSet.

Service.vb:

Public Class Service
    Implements IService
    Public Function PassDataSet(ByVal sXMLSchema As String, ByVal sXML As String) As Boolean Implements IService.PassDataSet
        Dim dsObjects As New Data.DataSet
        'First read the schema of the DataSet
        dsObjects.ReadXmlSchema(New MemoryStream(Text.Encoding.Unicode.GetBytes(sXMLSchema)))
        'Then read the data itself
        dsObjects.ReadXml(New MemoryStream(Text.Encoding.Unicode.GetBytes(sXML)))
        'Here do what ever you like with your DataSet

        'Finally return a value to the client
        Return True
    End Function
End Class

And finally here is how you call the method:

Client:

Dim proxy As New ServiceClient()
Dim dsDataSet As New DataSet()

'Here load your data in your DataSet

'Finally call the service
proxy.PassDataSet(dsDataSet.GetXmlSchema(), dsDataSet.GetXml())

Now you can enjoy your WCF service that accepts a DataSet 🙂

Creating a simple CheckListBox control in WPF

With .NET Framework 3.0 Microsoft has removed one control that I’ve liked and used a lot – the CheckListBox. But on the other hand with WPF the developer can easily create his own check list control. Here is how to create one yourself.
Put a simple ListBox in your window:
XAML:

<Window x:Class="winCustomPKChooser"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CheckListBox Demo" 
        Height="300" Width="300"
    >
    <ListBox x:Name="lstCheckListBox"
             Height="185"
               />
</Window>

The trick is that we will not add simple items to the list box, but instead of that we will add check boxes. Here is a simple function which adds items to our ListBox and hooks the corresponding events for when items get checked or unchecked:

VB:

Private Sub AddItemsToListBox()
     Dim chkCheckBoxToAdd as CheckBox
     For nLoop as Integer = 1 to 10
       chkCheckBoxToAdd = New CheckBox()
       chkCheckBoxToAdd.IsChecked = False
       chkCheckBoxToAdd.Content = "Item " & nLoop.ToString() 

       AddHandler chkCheckBoxToAdd.Checked _
             , AddressOf lstColumnName_ItemCheck
       AddHandler chkCheckBoxToAdd.Unchecked _
             , AddressOf lstColumnName_ItemUncheck

       lstColumnName.Items.Add(chkCheckBoxToAdd)
     Next
End Sub

Private Sub lstColumnName_ItemCheck(ByVal sender As Object _
    , ByVal e As System.Windows.RoutedEventArgs _ 
                        )
     'Do something when an item gets checked. 
     'If you need for something the checkbox 
     'which was checked use the CType(e.OriginalSource, CheckBox).
End Sub

Private Sub lstColumnName_ItemUncheck(ByVal sender As Object _
    , ByVal e As System.Windows.RoutedEventArgs _
   )
      'Do something when an item gets unchecked. 
      'If you need for something the checkbox 
      'which was unchecked use the CType(e.OriginalSource, CheckBox).
End Sub

Enjoy your own CheckListBox!

How to obfuscate WPF assemblies using obfuscation software for .NET Framework 2.0

I’ve read many posts over the Internet which are stating that it is currently impossible to obfuscate WPF assemblies. Well this is partially true.

Here is what you can do to partially protect your .NET Framework 3.0 code:
In order your code to continue to work properly you must exclude from the obfuscation at least the names of your WPF window and user control classes. You can leave in the obfuscation the variables, methods, events, etc. declared in the codebehind unless you use some of them in your markup. If this is the case you must exclude those too.

Note that by doing this you will not obfuscate the XAML code itself, but only the codebehind. Your markup can still be viewed with some disassembly tools (for example Lutz Roeder’s .NET reflector and the BamlViewer add-in).