Developed Custom .Net Font Dialog

Developed a Custom FontDialog as an alternative to the standard .Net FontDialog. Key advantage of CustomFontDialog is the full control over look and feel as it is open source. Source and binary files are available at sourceforge.

CustomFontDialog

CustomFontDialog avoids ‘This is not a True Type Font’ exception that affects the standard dialog in some cases. Most probably the exception happens when some installed fonts have invalid meta information. This exception cannot be caught using try/catch block because the exception is thrown from the code outside .Net framework. The exact exception message is ‘Only TrueType fonts are supported. This is not a TrueType font.’. CustomFontDialog gets around this problem by loading only True Type fonts. More details about the problem with standard dialog can be found here and here.

Moreover, CustomFontDialog provides easy access to recently used fonts by moving them at the top of the list in ‘Recently Used’ section.

Usage

Following C# code snippet demonstrates how to instantiate and display Custom FontDialog.

CustomFontDialog.FontDialog fontDialog = new CustomFontDialog.FontDialog();

// sets the default font
fontDialog.Font = new Font(FontFamily.GenericSansSerif, 10);

if (fontDialog.ShowDialog() == DialogResult.OK) {
   // Font is selected. Get the selected font using 'fontDialog.Font'
}
else {
   // FontDialog is canceled by the user
   // your code here to handle cancel action
}

For the CustomFontDialog to retain the recently selected fonts at the top of the list, the dialog should be instantiated only once and ShowDialog function should be called on the same object whenever the dialog needs to be displayed.

To programmatically add Fonts to be ‘Recently Used Fonts’ section, call AddFontToRecentList method.

Limitation: As compared to the standard FontDialog, CustomFontDialog doesn’t support changing text color.

 

Updates

 

Version 0.2.0 (31-May-2014)

Following fixes and enhancements are included in this version:

1- In Font List, arrow keys can be used to move between ‘Recently Used’ and ‘All Fonts’ sections.
2- When user starts typing in Font List, the focus shifts to the filter Text box automatically.
3- Whenever CustomFontDialog is displayed, the focus is on Font List by default.

Quick and dirty way of creating Numeric TextBox in .Net (C#)

Handle KeyDown event of the TextBox and set the e.Handled property to true if the character is not numeric.

this.myNumericTextBox.KeyDown +=
                       new KeyEventHandler(this.myNumericTextBox_KeyDown); 

 

private void myNumericTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyData)
            {
                case Keys.D0:
                case Keys.D1:
                case Keys.D2:
                case Keys.D3:
                case Keys.D4:
                case Keys.D5:
                case Keys.D6:
                case Keys.D7:
                case Keys.D8:
                case Keys.D9:
                case Keys.End:
                case Keys.Enter:
                case Keys.Home:
                case Keys.Back:
                case Keys.Delete:
                case Keys.Escape:
                case Keys.Left:
                case Keys.Right:
                    break;
                case Keys.Decimal:
                case (Keys)190: //decimal point
                    if (myNumericTextBox.Text.Contains('.'))
                    {
                        e.SuppressKeyPress = true;
                        e.Handled = true;
                    }
                    break;
                default:
                    e.SuppressKeyPress = true;
                    e.Handled = true;
                    break;
            }

        }

Switch cases list all desired characters which will be displayed, rest of the characters are ignored. If additional characters are required, they may be included as switch cases. For instance, negative sign may be allowed based on your requirement.

How to embed chrome browser in .net application

Chrome browser can be embedded in native application taking a hybrid approach to development where application is partly developed in native technology and partly in web. This has several advantages:

  • Salvage the existing investment in HTML/Javascript projects.
  • The part of application written in web technology is platform independent. This is very important due to variety of devices that are prevalent today.
  • Overcome the limitation of web technology and leverage the full power of the hardware through native code.

We need to know about three projects:

Project Type Description
Chromium Web Browser Chromium is the open source browser project which is behind Google Chrome.
ChromiumEmbedded
(CEF)
Web Browser Control Based on Chromium project, an open source embed-able Web Browser Control is developed called ChromiumEmbedded. ChromiumEmbedded supports programming interface for C++.
Xilium.CefGlue .Net Wrapper Quite a few wrappers are available to make ChromiumEmbedded accessible in other languages. The most updated and active wrapper for .Net is Xilium.CefGlue.

Follow the below steps to embed Chromium Web Browser control in your .Net application.

  1. Download the source code for Xilium from here (Click on the Branches tab and download the Master branch).
  2. Check for the current ChromiumEmbedded (CEF) build supported by Xilium here. As of now, the ChromiumEmbedded supported build is CEF 3.1547.1448. Download the relevant pre build binaries from here.
  3. Unzip the two downloaded files. Copy all DLLs from the Release folder of ChromuimEmbedded and place it in Debug folder of CefGlue.Demo.WinForms project in Xilium source code.
  4. Copy the locales folder under Resources from ChromuimEmbedded and place it in the Debug folder of CefGlue.Demo.WinForms project in Xilium source code.
  5. Open the Xilium source code in Visual Studio using Xilium.CefGlue.sln. Set CefGlue.Demo.WinForms as the startup project.
  6. Build and run the solution and you will get the demo .Net application running with embedded chromium browser.

Programmatically scroll Listbox in .Net (Windows Forms, C#)

It seems that .Net library doesn’t provide any way to scroll contents of ListBox through code. Selecting an item by setting SelectedIndex automatically scrolls the list to bring the item into view but this may not produce the desired effect. In my case, I wanted to programmatically select an item and make it the first visible item in the list. This effect cannot be achieved through changing SelectedIndex.

The way around this problem is to invoke Windows API SendMessage function.

To call a function from an un-managed DLL, we have to declare it along with DLLImport attribute.

[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg,
                                         uint wParam, uint lParam);

As the declaration shows, we have supply four arguments.

S/N Parameter Description
1 IntPtr hWnd This is the handle to ListBox Control. We can get the handle through Handle property of ListBox control e.g. myListBox.Handle
2 uint Msg This should be set as WM_VSCROLL. It says that we want to send message for scrolling vertically. Find list of messages that could be passed to a control here.
3 uint wParam This 32 bit parameter has two parts.

  • Lower 16 bits called LOWORD should specify one of the scroll bar commands. In our case, it should be SB_THUMBPOSITION.
  • Higher 16 bits called HIWORD should specify the numerical value for position of the scroll bar thumb. If we pass the index of a list item, list will scroll such that the item becomes the first visible item in the list.
4 uint lParam This parameter is for additional message specific information. For our purposes, we will just pass 0.

Following is the SendMessage function call to scroll the list. First, we define the constants WM_VSCROLL and SB_THUMBPOSITION. Then we develop the thrid paramter by combining LOWORD and HIWORD. Finally the function is called.

const uint WM_VSCROLL = 0x0115;
const uint SB_THUMBPOSITION = 4;

uint param = ((uint)(lstFont.SelectedIndex) << 16) |
                          (SB_THUMBPOSITION & 0xffff);

SendMessage(myListBox.Handle, WM_VSCROLL, param, 0);

Custom .Net (C#) Collection: Recently Used List

I came across a situation where I needed a collection which can hold recently used objects of a particular kind. For instance, recently opened files, recently used fonts or colors etc. Such a list should demonstrate following behavior:

  • List should have a limited size (or call it maximum size). As list grows beyond the maximum size, the oldest item should be dropped.
  • Newly added items should be inserted at the top of the list i.e. index 0.
  • If an item to be added already exists in the list, it should be moved to the top of the list (at index 0) rather than being duplicated. This means that entries in the list will always be unique and order of the items will follow how recently they were used.

Following custom collection class provides this functionality:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyNamespace
{
    
    public class RecentlyUsedList<T>
    {
        
        public RecentlyUsedList(int maxSize)
        {
            this.maxSize = maxSize;
        }

        private List<T> list = new List<T>();

        public T this[int i]
        {
            get
            {
                return list[i];
            }            
        }

        private int maxSize;

        public int MaxSize
        {
            get
            {
                return maxSize;
            }                      
        }

        public int Count
        {
            get
            {
                return list.Count;
            }
        }

        public void Add(T item)
        {
            int i = list.IndexOf(item);
            if (i != -1)    list.RemoveAt(i);

            if (list.Count == MaxSize) list.RemoveAt(list.Count - 1);

            list.Insert(0, item);
        }
    
    }
}

One nice enhancement to the class would be to implement System.Collections.IEnumerable interface. It will enable the collection to be iterated using foreach loop.

Handle arrow key events in Windows Forms .Net (C#)

Pressing of a key is detected and handled in Windows Form using KeyPress, KeyDown or similar events.

this.KeyDown += myForm_KeyDown;

private void myForm_KeyDown(object sender, KeyEventArgs e)
{
   //Your code here
}

But these events does not fire when arrow keys are pressed. One way to get around it is to set KeyPreview as true for your Form. In many cases, this also doesn’t work, for instance, when you have buttons on your Form.

In such cases, ProcessCmdKey can be overridden to detect and handle arrow key events.

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
       switch(keyData)
       {
           case Keys.Down:
               //Handle down arrow key event
               break;
           case Keys.Up:
               //Handle up arrow key event
               break;
           case Keys.Right:
               //Handle right arrow key event
               break;
           case Keys.Left:
               //Handle left arrow key event
               break;
        }
        return base.ProcessCmdKey(ref msg, keyData);
}

After handling the arrow key event if you do not want the standard arrow key functionality to kick in, return true rather than calling return base.ProcessCmdKey(ref msg, keyData); Standard functionality could be to move focus to the next or previous control.

Returning true from ProcessCmdKey means event has been handled and should not be routed further for processing.

Excel Add-in for Exporting data to XML

Introduction

ExcelExportXML is a Microsoft Excel 2010 Add-in that generates XML data from excel sheet. It is developed in Visual Studio 2010 using C#.

It is a very simple add-in. To understand how to works, consider an excel sheet having following data.

Country Capital Continent
France Paris Europe
Germany Berlin Europe
India New Delhi Asia
Indonesia Jakarta Asia

Using the add-in, above can be exported to following Xml.

<sheet1>
    <row>
        <country>France</country>
        <capital>Paris</capital>
        <continent>Europe</continent>
    </row>
    <row>
        <country>Germany</country>
        <capital>Berlin</capital>
        <continent>Europe</continent>
    </row>
    <row>
        <country>India</country>
        <capital>New Delhi</capital>
        <continent>Asia</continent>
    </row>
    <row>
        <country>Indonesia</country>
        <capital>Jakarta</capital>
        <continent>Asia</continent>
    </row>
</sheet1>

Once the Add-in is installed, you will have a ‘Generate XML’ button on Add-ins tab of Excel Ribbon as shown below. Clicking ‘Generate XML’ will pop up the save file dialog which will allow you to save the generated Xml file.

ScreenShot.png

Use Case & Assumptions

ExcelExportXml is useful when you have tabular data in excel and the first row contains the column headings. It works based on following assumptions.

  1. First row is considered as column headers and will be converted to Xml tags.
  2. After encountering the first empty cell in header row, rest of the columns to the right will be ignored.
  3. Supports columns up to ‘Z’ only i.e. maximum of 26 columns.
  4. First row for which all values are empty will be considered the end of sheet.
  5. Sheet name and column names should not have any spaces.

Why not use standard Save As Xml functionality

Excel provides more than one ways to export xml data. One of them is ‘Save As Xml Data’ available in Save As dialog. This requires Xml Mappings to be defined which I believe requires developer Add-in from Microsoft to be installed.

Another option is ‘Save As Xml Spreedsheet 2003’ which generates following Xml.

<Worksheet ss:Name="Sheet1">
  <Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="5" x:FullColumns="1"
   x:FullRows="1" ss:DefaultRowHeight="15">
   <Column ss:Width="51"/>
   <Column ss:Width="54"/>
   <Column ss:Width="51.75"/>
   <Row ss:StyleID="s64">
    <Cell><Data ss:Type="String">Country</Data></Cell>
    <Cell><Data ss:Type="String">Capital</Data></Cell>
    <Cell><Data ss:Type="String">Continent</Data></Cell>
   </Row>
   <Row>
    <Cell><Data ss:Type="String">France</Data></Cell>
    <Cell><Data ss:Type="String">Paris</Data></Cell>
    <Cell><Data ss:Type="String">Europe</Data></Cell>
   </Row>
   <Row>
    <Cell><Data ss:Type="String">Germany</Data></Cell>
    <Cell><Data ss:Type="String">Berlin</Data></Cell>
    <Cell><Data ss:Type="String">Europe</Data></Cell>
   </Row>
   <Row>
    <Cell><Data ss:Type="String">India</Data></Cell>
    <Cell><Data ss:Type="String">New Delhi</Data></Cell>
    <Cell><Data ss:Type="String">Asia</Data></Cell>
   </Row>
   <Row>
    <Cell><Data ss:Type="String">Indonesia</Data></Cell>
    <Cell><Data ss:Type="String">Jakarta</Data></Cell>
    <Cell><Data ss:Type="String">Asia</Data></Cell>
   </Row>
  </Table>
  </Worksheet>

As you can see, the above might not be what you want. It is more a representation of excel sheet than semantics of your data. ExcelExportXML is quite limited but effective in a common scenario where you have tabular data and the first row contains column headers.

Links

Writing Add-in for Microsoft Excel 2010 using Visual Studio 2010

Using Visual Studio 2010 Professional, creating Excel Add-in is pretty simple. Following are the steps I followed for writing an Add-In for exporting Xml:

Step # 1

Create new project of type ‘Excel 2010 Add-in’. The project will have a class file called ThisAddin.cs.

Step # 2

For creating a button on the Excel ribbon, right click on the project and select Add – > New Item.

Step # 3

Select ‘Ribbon (XML)’ from the list of new items and name the ribbon class, say Ribbon1. This will add two files to the project which are Ribbon1.cs and Ribbon1.xml.

Step # 4

Add the following code in ThisAddin class

protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
    return new Ribbon1();
}
Step # 5

In Ribbon1.xml define the properties of the button that will be displayed on the Excel ribbon. The onAction attribute specifies the method which will be called from Ribbon1.cs on clicking the button (onAction="OnTextButton").

 <?xml version="1.0" encoding="UTF-8"?>
	<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
	  <ribbon>
	    <tabs>
	      <tab idMso="TabAddIns">
	        <group id="MyGroup"
	               label="Export XML">
	          <button id="textButton" label="Generate XML"
	             screentip="Export to XML" onAction="OnTextButton"
	             supertip="Export excel sheet to XML file."/>
	        </group>
	      </tab>
	    </tabs>
	  </ribbon>
	</customUI>
Step # 6

Add following method declaration to Ribbon1.cs and implement your functionality here.

public void OnTextButton(Office.IRibbonControl control)
{
    //TODO:Add your implementation here
} 

Links:

ASP.Net Web Forms vs ASP.NET MVC

When microsoft released ASP.Net, it was thought that it would relieve the need to master HTML and related technologies for most use cases. It will bring the web development closer to windows forms development model with both having similar controls and tools. In ASP.Net forms, we would be able to drag a data grid, drop it on to a page and bind it to a data source, the same way we used to do for windows apps.

Initially I was excited about the idea. Coming from a windows development background, it made things simpler for me. As I did more work with ASP.Net, something didn’t look right. It was very easy to do things you do most of the time in the most common way. But if you want to do something little bit different, then the complexity of the platform made it ridiculously difficult. ASP.Net forms had some significant improvements over ASP but, in hindsight, I think the power and simplicity of HTML, CSS and JavaScript was underestimated.

With ASP.Net MVC, the focus is back on the key web technologies and it feels so much better.

For a detailed comparison between the two technologies, see:

http://msdn.microsoft.com/en-us/magazine/dd942833.aspx
http://weblogs.asp.net/shijuvarghese/archive/2008/07/09/asp-net-mvc-vs-asp-net-web-form.aspx

For learning ASP.Net MVC, I would recommend the Pluralsight video tutorial at ASP.Net MVC website.

Reached “Design – All Star” in design .toolbox

"All Star - Design" @ .toolbox

.toolbox is a really fun environment to learn basic design concepts as well as the fundamentals of creating Silverlight applications using Expression Studio. Today, I finished both the tracks (i.e. principles and scenarios) and achieved all 15 badges. The high quality tutorials and evaluations, and a very nice theme make it really enjoyable. Check it out at http://www.microsoft.com/design/toolbox/