How to set a flat style to Button and ComboBox in WPF

In XAML:

1
2
3
4
5
6
7
8
9
<Button
   Name="myComboBox"
   Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
/>
 
<ComboBox
   Name="myButton"
   Style="{StaticResource {x:Static ToolBar.ComboBoxStyleKey}}"
/>
<Button
   Name="myComboBox"
   Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
/>

<ComboBox
   Name="myButton"
   Style="{StaticResource {x:Static ToolBar.ComboBoxStyleKey}}"
/>

In code (C#):

1
2
3
4
5
myButton.Style =
    (Style)FindResource(ToolBar.ButtonStyleKey);
 
myComboBox.Style = (Style)FindResource(ToolBar.ComboBoxStyleKey);
myComboBox.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
myButton.Style =
    (Style)FindResource(ToolBar.ButtonStyleKey);

myComboBox.Style = (Style)FindResource(ToolBar.ComboBoxStyleKey);
myComboBox.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
 

How to count the frequency of the words in a text

Here is the sample code wirtten in c#:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System;
using System.IO;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Text.RegularExpressions;
 
namespace CountWords
{
    class Program
    {
        static void Main(string[] args)
        {
            string fullBook = File.ReadAllText("C:\\TEMP\\Kapital.txt", System.Text.Encoding.UTF7);
            
            //remove numbers and punctuation
            fullBook = Regex.Replace(fullBook, "\\.|;|:|,|[0-9]|’", " ");
            
            //create collection of words
            var wordCollection = Regex.Matches(fullBook, @"[\w|ä]+");
            
            //calculate word frequencies
            var dict = new Dictionary<String, int>();
            for (int i = 0; i < wordCollection.Count; i++)
            {
                string word = wordCollection[i].Value;
                if (!dict.ContainsKey(word))
                    dict[word] = 1;
                else
                    ++dict[word];
            }
            Console.WriteLine("unique words : " + dict.Count);
            Console.WriteLine("total words : " + wordCollection.Count);
 
            using (StreamWriter streamWrite = new StreamWriter("C:\\TEMP\\OUTPUT.csv"))
            {
                foreach (KeyValuePair<String, int> kv in dict)
                    streamWrite.WriteLine("\"{0}\",\"{1}\"", kv.Key, kv.Value);
            }
            Console.ReadKey();
        }
    }
}
using System;
using System.IO;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace CountWords
{
    class Program
    {
        static void Main(string[] args)
        {
            string fullBook = File.ReadAllText("C:\\TEMP\\Kapital.txt", System.Text.Encoding.UTF7);
            
            //remove numbers and punctuation
            fullBook = Regex.Replace(fullBook, "\\.|;|:|,|[0-9]|’", " ");
            
            //create collection of words
            var wordCollection = Regex.Matches(fullBook, @"[\w|ä]+");
            
            //calculate word frequencies
            var dict = new Dictionary<String, int>();
            for (int i = 0; i < wordCollection.Count; i++)
            {
                string word = wordCollection[i].Value;
                if (!dict.ContainsKey(word))
                    dict[word] = 1;
                else
                    ++dict[word];
            }
            Console.WriteLine("unique words : " + dict.Count);
            Console.WriteLine("total words : " + wordCollection.Count);

            using (StreamWriter streamWrite = new StreamWriter("C:\\TEMP\\OUTPUT.csv"))
            {
                foreach (KeyValuePair<String, int> kv in dict)
                    streamWrite.WriteLine("\"{0}\",\"{1}\"", kv.Key, kv.Value);
            }
            Console.ReadKey();
        }
    }
}

The diagram below depicts the results of parsing the “Das Kapital” by Karl Marx (top 30 words).
Das Kapital

 

How to find all subclasses of a given class

The following function will return a list of all subclasses inherited from a given class. Please note, that it works only within a single assembly, same as which holds the given superclass.

1
2
3
4
5
6
7
8
Function FindSubClasses(Of TBaseType)() As IEnumerable(Of Type)
    Dim baseType = GetType(TBaseType)
    Dim assembly = baseType.Assembly
 
    Return From t In assembly.GetTypes()
        Where t.IsSubclassOf(baseType)
        Select t
End Function
Function FindSubClasses(Of TBaseType)() As IEnumerable(Of Type)
    Dim baseType = GetType(TBaseType)
    Dim assembly = baseType.Assembly

    Return From t In assembly.GetTypes()
        Where t.IsSubclassOf(baseType)
        Select t
End Function

Next function will return all classes implementing a given interface:

1
2
3
4
5
6
7
8
Function FindClassesImplementedInterface(Of TInterface)() As IEnumerable(Of Type)
    Dim baseInterface = GetType(TInterface)
    Dim assembly = baseInterface.Assembly
 
    Return From t In assembly.GetTypes()
        Where t.IsAssignableFrom(baseInterface)
        Select t
End Function
Function FindClassesImplementedInterface(Of TInterface)() As IEnumerable(Of Type)
    Dim baseInterface = GetType(TInterface)
    Dim assembly = baseInterface.Assembly

    Return From t In assembly.GetTypes()
        Where t.IsAssignableFrom(baseInterface)
        Select t
End Function

Happy coding!

 

How to align text in DataGrid

The obvious solution is to set a HorizontalAlignment property of DataGridCell style:

1
2
3
4
5
6
7
<DataGridTextColumn Binding="{Binding Quantity, StringFormat='#,0.0000'}" ClipboardContentBinding="{x:Null}" Header="Quantity">
    <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell" >
            <Setter Property="HorizontalAlignment" Value="Right" />
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Quantity, StringFormat='#,0.0000'}" ClipboardContentBinding="{x:Null}" Header="Quantity">
    <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell" >
            <Setter Property="HorizontalAlignment" Value="Right" />
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

But this gives a bad side-effect when you select a row in your DataGrid:

To avoid this, instead of using CellStyle, you can apply ElementStyle targeting to TextBlock, which holds the text in DataGridTextColumn:

1
2
3
4
5
6
7
<DataGridTextColumn Binding="{Binding Quantity, StringFormat='#,0.0000'}" ClipboardContentBinding="{x:Null}" Header="Quantity">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="TextAlignment" Value="Right" />
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Quantity, StringFormat='#,0.0000'}" ClipboardContentBinding="{x:Null}" Header="Quantity">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="TextAlignment" Value="Right" />
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

That works nicely:

Happy coding!

 

How to create an object by class name using Reflection

1. When the class is defined in the same assembly, where your code is executed:

1
2
3
4
Dim _assemblyName As String = "MyAssembly"
Dim _typeName As String = "MyNamespace.ExampleControl"
Dim _type As Type = Assembly.Load(_assemblyName).GetType(_typeName, True)
_control = Activator.CreateInstance(_type)
Dim _assemblyName As String = "MyAssembly"
Dim _typeName As String = "MyNamespace.ExampleControl"
Dim _type As Type = Assembly.Load(_assemblyName).GetType(_typeName, True)
_control = Activator.CreateInstance(_type)

2. If the class remains in a different assembly, then you will need to provide a full qualified assembly name, like
“ExampleAssembly, Version=1.0.0.0, Culture=en, PublicKeyToken=a5d015c7d5a0b012” (see more about the full qualified assembly names here: http://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.aspx)

For instance, if you need to create an instance of System.Windows.Controls.DatePicker control:

1
2
3
4
Dim _assemblyName As String = "PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Dim _typeName As String = "System.Windows.Controls.DatePicker"
Dim _type As Type = Assembly.Load(_assemblyName).GetType(_typeName, True)
_control = Activator.CreateInstance(_type)
Dim _assemblyName As String = "PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Dim _typeName As String = "System.Windows.Controls.DatePicker"
Dim _type As Type = Assembly.Load(_assemblyName).GetType(_typeName, True)
_control = Activator.CreateInstance(_type)

3. If, for any reason, you need to use a short assembly name, like “PresentationFramework” rather than a full qualified name given in previous example, then you can use the deprecated function LoadLoadWithPartialName, like in the following example:

1
2
3
4
Dim _assemblyName As String = "PresentationFramework"
Dim _typeName As String = "System.Windows.Controls.DatePicker"
Dim _type As Type = Assembly.LoadLoadWithPartialName(_assemblyName).GetType(_typeName, True)
_control = Activator.CreateInstance(_type)
Dim _assemblyName As String = "PresentationFramework"
Dim _typeName As String = "System.Windows.Controls.DatePicker"
Dim _type As Type = Assembly.LoadLoadWithPartialName(_assemblyName).GetType(_typeName, True)
_control = Activator.CreateInstance(_type)

For more information about the reflection, please refer to MSDN: http://msdn.microsoft.com/en-us/library/f7ykdhsy(v=vs.110).aspx.

 

How to dynamically generate SSRS Report

SSRS is a wonderful tool for quickly retrieving data and presenting it to the user in a format predefined at design-time. But what if there is a need to create a new report at run-time, based on some dynamic data structure or any specific user needs? Of course, for advanced business users Microsoft Report Builder is an option, but often developers may need to have full control on the generating the reports on their own, and in such case as a solution I would recommend just to create an RDL file which is nothing else than XML written using Report Definition Language for which the thorough specification exists in MSDN under the following links:

Report Definition Language (SSRS)

SQL Server RDL Specification

In this post, I’d like to provide a very simple example of using this technique in VB.Net application which demonstrates how to generate and then preview a new report in following steps:

1. A new RDL is being created based on a data returned by a given SQL statement.
2. Newly created RDL is used as source of LocalReport in ReportViewer control.
3. A data source (DataReader) is bind to LocalReport and, finally, the report is rendered and opened in ReportViewer.

For simplicity, the sample report contains only two elements: a title (TextBox) and a table (Tablix) in a predefined format. The dynamic part is that the title can be provided by a user, and the column list in the table is build based on the fields returned by SQL provided by the user.

The report template is saved as XML file RDLTemplate.xml – be sure when building the project that the file is copied to the output directory (property “Copy to Output Directory” is set to “Copy always”). In code we just fill some missed parts in this XML by using String.Format method and after all save the XML as RDL file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        Using streamReader As New StreamReader(Directory.GetCurrentDirectory + "\RDLTemplate.xml")
            '{0} - Report Title
            '{1} - Tablix Columns
            '{2} - Header Row Cells 
            '{3} - Detail Row Cells
            '{4} - Tablix Members
            '{5} - Connection String
            '{6} - SQL Statement
            '{7} - Table Fields
            '{8} - Report GUID
            '{9} - DataSource GUID
            xml = String.Format(streamReader.ReadToEnd(), _
                    txtReportTitle.Text, _
                    GetTablixColumns(dataReader.FieldCount), _
                    GetTableCells(dataReader, "lbl", "{0}"), _
                    GetTableCells(dataReader, "txt", "=Fields!{0}.Value"), _
                    GetTablixMembers(dataReader.FieldCount), _
                    txtConnectionString.Text, _
                    txtSQL.Text, _
                    GetFields(dataReader), _
                    System.Guid.NewGuid().ToString(), _
                    System.Guid.NewGuid().ToString())
        End Using
        Using streamReader As New StreamReader(Directory.GetCurrentDirectory + "\RDLTemplate.xml")
            '{0} - Report Title
            '{1} - Tablix Columns
            '{2} - Header Row Cells 
            '{3} - Detail Row Cells
            '{4} - Tablix Members
            '{5} - Connection String
            '{6} - SQL Statement
            '{7} - Table Fields
            '{8} - Report GUID
            '{9} - DataSource GUID
            xml = String.Format(streamReader.ReadToEnd(), _
                    txtReportTitle.Text, _
                    GetTablixColumns(dataReader.FieldCount), _
                    GetTableCells(dataReader, "lbl", "{0}"), _
                    GetTableCells(dataReader, "txt", "=Fields!{0}.Value"), _
                    GetTablixMembers(dataReader.FieldCount), _
                    txtConnectionString.Text, _
                    txtSQL.Text, _
                    GetFields(dataReader), _
                    System.Guid.NewGuid().ToString(), _
                    System.Guid.NewGuid().ToString())
        End Using

Please note, that even though the Data Source is defined in RDL, when using it as a local report (ReportViewer.LocalReport) you need to provide your ReportViewer with an actual data source, which can be either of type DataTable, DataReader or any other appropriate:

1
2
3
4
        Dim reportDataSource As ReportDataSource = New ReportDataSource("ReportDataSet", dataReader)
 
        ReportViewer1.LocalReport.DataSources.Clear()
        ReportViewer1.LocalReport.DataSources.Add(reportDataSource)
        Dim reportDataSource As ReportDataSource = New ReportDataSource("ReportDataSet", dataReader)

        ReportViewer1.LocalReport.DataSources.Clear()
        ReportViewer1.LocalReport.DataSources.Add(reportDataSource)

Other way of using the generated RDL is to upload it to existing SSRS server using the SSRS web service and then link ReportViewer.ServerReport to it. In this case you won’t need to bind a data source to ReportViewer, since SQL Server will do all the magic for you itself.
If you successfully build the project, run it, change SQL connection string and SQL as you need and click “Generate and Run Report” button, and if everything went fine, you will see the result of your work:

screenshot

The full source of the sample you will find here: RDLSample.zip.Hope it will be a good starting point in developing of your own nice report builder.

 

How to handle Keyboard Focus Events globally in WPF

You will find quite a few cases when your application would need to handle the changing of keyboard focus globally at application level, not just on a single control element or even a form level. The simple adding listeners to all possible elements will not be an effective way and doesn’t guarantee you to have full control on these events.

More effective and reliable would be to register a handler for routed events Keyboard.PreviewGotKeyboardFocusEvent and Keyboard.PreviewLostKeyboardFocusEvent.

The registering can be done by EventManager.RegisterClassHandler method with the following syntax:

1
2
3
4
5
EventManager.RegisterClassHandler( _
    GetType(UIElement), _
    Keyboard.PreviewGotKeyboardFocusEvent, _
    New KeyboardFocusChangedEventHandler( _
        AddressOf OnElementGotKeyboardFocus))
EventManager.RegisterClassHandler( _
    GetType(UIElement), _
    Keyboard.PreviewGotKeyboardFocusEvent, _
    New KeyboardFocusChangedEventHandler( _
        AddressOf OnElementGotKeyboardFocus))

It should be used with attention though, because due to the fact that they are preview events, this method may lead to the wrong results if some element in between has marked the event as handled.

The attached WPF example project demonstrates how to update the application’s status bar with the ToolTip text of the selected/focused control (of course this concrete thing can be done in more elegant ways, but just for a simple example).
screenshot
The example project can be downloaded from here: GlobalFocusHandling.zip.

 

How to use SSRS Web Service from Java

 

  1. Import the reporting service wsdl using wsimport tool which is available in JDK starting from v1.6:
    wsimport.exe http://<server>/reportserver/reportService2005.asmx?wsdl -s  -extension</server>
  2. Copy the resulting package to your java project. Amon other things, it will contain the ReportingService2005 class and the ReportingService2005Soap interface which are the main point of your interest.
    Continue reading…
 

How to serialize objects in VBA

Generally speaking, VBA doesn’t provide the possibility to serialize objects, and if you are interested in this topic, you might seen quite a few blogs around this thing, and the answer is always the same – generically not possible, period.

But nothing is impossible though. This article describes a workaround which will give you a general way to serialize any type of objects, including those derived from the native VBA classes (e.g. Workbook etc), custom VBA classes and the COM objects.
Continue reading…

 

How to exclusively lock a table in MS SQL

Start a transaction and select from the table using the (TABLOCKX) hint.

As the result, read from this table outside of the transaction will be queued until the transaction is committed or rolled back.

1
2
3
4
5
6
7
8
BEGIN TRAN  
 
SELECT    * 
FROM      Table1 (TABLOCKX)    
 
WAITFOR DELAY '00:00:30'    
 
ROLLBACK TRAN
BEGIN TRAN  

SELECT    * 
FROM      Table1 (TABLOCKX)    

WAITFOR DELAY '00:00:30'    

ROLLBACK TRAN