Skip Ribbon Commands
Skip to main content

Blog

:

Quick Launch

Home
Blog of Alex Arkhipov, containing my thoughts, comments and questions.
March 13
Disabling Submit Button from AJAX Update Panel to Prevent Double Posting

It’s a fairly trivial task in ASP.NET to disable Submit button or LinkButton after user clicks on it to prevent immediate second submit while page is still refreshing. This problem sometime referenced as a double-click issue while it’s actually not related to the double-click control event. Anyway, there are many solutions around, but I couldn’t find anything working with AJAX update panel and ASP.NET validators on the page. Here is the solution I came up with.

Prerequisites: ASP.NET page (master page is the best place) with script manager and update panel(s).

Place the following code into the header of the page:

<script type="text/javascript">

 

    function pageLoad(sender, args) {

        var rm = Sys.WebForms.PageRequestManager.getInstance();

        rm.add_initializeRequest(initializeRequest);

        rm.add_endRequest(endRequest);

    }

 

    function initializeRequest(sender, args) {

        //Disable button to prevent double submit

        var btn = $get(args._postBackElement.id);

        if (btn) {

            btn.disabled = true;

            if (btn.className == 'button')

                btn.className = 'buttonDisabled';

        }

    }

 

    function endRequest(sender, args) {

        //Re-enable button

        var btn = $get(sender._postBackSettings.sourceElement.id);

        if (btn) {

            btn.disabled = false;

            if (btn.className == 'buttonDisabled')

                btn.className = 'button';

        }

    }

 

</script>

 

Vuala! You don’t need to modify buttons and link buttons with custom JavaScript anymore. Everything is done automatically. The way it works is pretty simple. The pageLoad function called from the Script Manager when page is served to the client. It registers page event handlers: The initializeRequest function will disable the button, and endRequest will re-enable it. Swapping CSS class is optional.
February 26
Visual Studio 2008 Power Commands

It's a very useful set of free tools Microsoft put together to address some limitations of Visual Studio 2008 IDE.

 

 

Download from here: http://code.msdn.microsoft.com/PowerCommands

 

Features description from their website:

Enable/Disable PowerCommands in Options dialog
This feature allows you to select which commands to enable in the Visual Studio IDE. Point to the Tools menu, then click Options. Expand the PowerCommands options, then click Commands. Check the commands you would like to enable.
Note: All power commands are initially defaulted Enabled.

Format document on save / Remove and Sort Usings on save
The Format document on save option formats the tabs, spaces, and so on of the document being saved. It is equivalent to pointing to the Edit menu, clicking Advanced, and then clicking Format Document. The Remove and sort usings option removes unused using statements and sorts the remaining using statements in the document being saved.
Note: The Remove and sort usings option is only available for C# documents.
Note: Format document on save and Remove and sort usings both are initially defaulted OFF.

Clear All Panes
This command clears all output panes. It can be executed from the button on the toolbar of the Output window.

Copy Path
This command copies the full path of the currently selected item to the clipboard. It can be executed by right-clicking one of these nodes in the Solution Explorer:
The solution node; A project node; Any project item node; Any folder.

Email CodeSnippet
To email the lines of text you select in the code editor, right-click anywhere in the editor and then click Email CodeSnippet.

Insert Guid Attribute
This command adds a Guid attribute to a selected class. From the code editor, right-click anywhere within the class definition, then click Insert Guid Attribute.

Show All Files
This command shows the hidden files in all projects displayed in the Solution Explorer when the solution node is selected. It enhances the Show All Files button, which normally shows only the hidden files in the selected project node.

Undo Close
This command reopens a closed document , returning the cursor to its last position. To reopen the most recently closed document, point to the Edit menu, then click Undo Close. Alternately, you can use the CtrlShiftZ shortcut.
To reopen any other recently closed document, point to the View menu, click Other Windows, and then click Undo Close Window. The Undo Close window appears, typically next to the Output window. Double-click any document in the list to reopen it.

Collapse Projects
This command collapses a project or projects in the Solution Explorer starting from the root selected node. Collapsing a project can increase the readability of the solution. This command can be executed from three different places: solution, solution folders and project nodes respectively.

Copy Class
This command copies a selected class entire content to the clipboard, renaming the class. This command is normally followed by a Paste Class command, which renames the class to avoid a compilation error. It can be executed from a single project item or a project item with dependent sub items.

Paste Class
This command pastes a class entire content from the clipboard, renaming the class to avoid a compilation error. This command is normally preceded by a Copy Class command. It can be executed from a project or folder node.

Copy References
This command copies a reference or set of references to the clipboard. It can be executed from the references node, a single reference node or set of reference nodes.

Paste References
This command pastes a reference or set of references from the clipboard. It can be executed from different places depending on the type of project. For CSharp projects it can be executed from the references node. For Visual Basic and Website projects it can be executed from the project node.

Copy As Project Reference
This command copies a project as a project reference to the clipboard. It can be executed from a project node.

Edit Project File
This command opens the MSBuild project file for a selected project inside Visual Studio. It combines the existing Unload Project and Edit Project commands.

Open Containing Folder
This command opens a Windows Explorer window pointing to the physical path of a selected item. It can be executed from a project item node

Open Command Prompt
This command opens a Visual Studio command prompt pointing to the physical path of a selected item. It can be executed from four different places: solution, project, folder and project item nodes respectively.

Unload Projects
This command unloads all projects in a solution. This can be useful in MSBuild scenarios when multiple projects are being edited. This command can be executed from the solution node.

Reload Projects
This command reloads all unloaded projects in a solution. It can be executed from the solution node.

Remove and Sort Usings
This command removes and sort using statements for all classes given a project. It is useful, for example, in removing or organizing the using statements generated by a wizard. This command can be executed from a solution node or a single project node.

Extract Constant
This command creates a constant definition statement for a selected text. Extracting a constant effectively names a literal value, which can improve readability. This command can be executed from the code editor by right-clicking selected text.

Clear Recent File List
This command clears the Visual Studio recent file list. The Clear Recent File List command brings up a Clear File dialog which allows any or all recent files to be selected.

Clear Recent Project List
This command clears the Visual Studio recent project list. The Clear Recent Project List command brings up a Clear File dialog which allows any or all recent projects to be selected.

Transform Templates
This command executes a custom tool with associated text templates items. It can be executed from a DSL project node or a DSL folder node.

Close All
This command closes all documents. It can be executed from a document tab.
November 18
Converting Unicode Punctuation to Basic Latin (ASCII)

Recently I spent fair amount of time researching issues with Unicode. More than often copy-pasting from Word document would result in some corrupted text after processing the form. What I found is that Word replaces some input with Unicode characters. Em-dash, ellipsis, trademark, copyright, and some quotation marks for example.

I wrote a method to convert Unicode punctuation characters to the Basic Latin (a.k.a. ASCII). It’s not absolute and ultimate tool by any means, so you are welcome to extend it with your own cases.

I used Unicode charts with HEX values found on the official Unicode site. At the end of every sheet you can find substitution examples for most common characters. The idea was to replace these offensive characters with ASCII equivalent. For example ellipsis would become "...", em-dash - "--", etc.

/// <summary>

/// This method converts common punctuation in the supplied string

/// to its equivalent in Basic Latin (ASCII).

/// See Unicode charts http://unicode.org/charts/ for more info

/// </summary>

/// <param name="input">String to convert</param>

/// <returns>String converted to basic latin with Unicode punctuation replaced.</returns>

public string ConvertToBasicLatin(string input)

{

    //Replace combined characters

    //Ellipsis

    input = input.Replace(((char)0x2026).ToString(), "...");

    input = input.Replace(((char)0x2025).ToString(), "..");

    //Em-dash

    input = input.Replace(((char)0x2014).ToString(), "--");

    //Fractures

    input = input.Replace(((char)0x00BC).ToString(), "1/4");

    input = input.Replace(((char)0x00BD).ToString(), "1/2");

    input = input.Replace(((char)0x00BE).ToString(), "3/4");

    input = input.Replace(((char)0x2153).ToString(), "1/3");

    input = input.Replace(((char)0x2154).ToString(), "2/3");

    input = input.Replace(((char)0x2155).ToString(), "1/5");

    input = input.Replace(((char)0x2156).ToString(), "2/5");

    input = input.Replace(((char)0x2158).ToString(), "4/5");

    input = input.Replace(((char)0x2159).ToString(), "1/6");

    input = input.Replace(((char)0x215A).ToString(), "5/6");

    input = input.Replace(((char)0x215B).ToString(), "1/8");

    input = input.Replace(((char)0x215C).ToString(), "3/8");

    input = input.Replace(((char)0x215D).ToString(), "5/8");

    input = input.Replace(((char)0x215E).ToString(), "7/8");

    input = input.Replace(((char)0x215F).ToString(), "1/");

    //Exclamation - Question mark

    input = input.Replace(((char)0x2048).ToString(), "?!");

    input = input.Replace(((char)0x2049).ToString(), "!?");

    //Copyrights

    input = input.Replace(((char)0x00A9).ToString(), "(C)");

    //Trademarks

    input = input.Replace(((char)0x00AE).ToString(), "(R)");

    input = input.Replace(((char)0x2120).ToString(), "(SM)");

    input = input.Replace(((char)0x2122).ToString(), "(TM)");

 

    //Array with replacament values for single characters

    int[][] unicodeMatrix = new int[][]

    {

        //Spaces

        new int[2] {0x00A0,0x0020},

        new int[2] {0x200B,0x0020},

        new int[2] {0x2060,0x0020},

        new int[2] {0x3000,0x0020},

        new int[2] {0xFEFF,0x0020},

        // Exclamation

        new int[2] {0x00A1,0x0021},

        new int[2] {0x01C3,0x0021},

        new int[2] {0x203C,0x0021},

        new int[2] {0x203D,0x0021},

        new int[2] {0x2762,0x0021},

        //Quotation

        new int[2] {0x02BA,0x0022},

        new int[2] {0x02DD,0x0022},

        new int[2] {0x02EE,0x0022},

        new int[2] {0x02F5,0x0022},

        new int[2] {0x02F6,0x0022},

        new int[2] {0x030B,0x0022},

        new int[2] {0x030E,0x0022},

        new int[2] {0x2033,0x0022},

        new int[2] {0x2036,0x0022},

        new int[2] {0x3003,0x0022},

        new int[2] {0x00AB,0x0022},

        new int[2] {0x00BB,0x0022},

        new int[2] {0x201C,0x0022},

        new int[2] {0x201D,0x0022},

        new int[2] {0x201E,0x0022},

        new int[2] {0x201F,0x0022},

        //# sign

        new int[2] {0x2114,0x0023},

        new int[2] {0x266F,0x0023},

        //% sign

        new int[2] {0x066A,0x0025},

        new int[2] {0x2030,0x0025},

        new int[2] {0x2031,0x0025},

        new int[2] {0x2052,0x0025},

        //Single quote

        new int[2] {0x2018,0x0027},

        new int[2] {0x2019,0x0027},

        new int[2] {0x201A,0x0022},

        new int[2] {0x201B,0x0022},

        new int[2] {0x02B9,0x0027},

        new int[2] {0x02BB,0x0027},

        new int[2] {0x02BC,0x0027},

        new int[2] {0x02BD,0x0027},

        new int[2] {0x02CA,0x0027},

        new int[2] {0x02CB,0x0027},

        new int[2] {0x02C8,0x0027},

        new int[2] {0x0301,0x0027},

        new int[2] {0x2032,0x0027},

        new int[2] {0xA78C,0x0027},

        new int[2] {0x0060,0x0027},

        new int[2] {0x02CB,0x0027},

        new int[2] {0x0300,0x0027},

        new int[2] {0x2035,0x0027},

        new int[2] {0x00B4,0x0027},

        //Undertscore

        new int[2] {0x02CD,0x005F},

        new int[2] {0x0331,0x005F},

        new int[2] {0x0332,0x005F},

        new int[2] {0x2017,0x005F},

        //Hyphen

        new int[2] {0x2010,0x002D},

        new int[2] {0x2011,0x002D},

        new int[2] {0x2012,0x002D},

        new int[2] {0x2013,0x002D},

        new int[2] {0x2212,0x002D},

        new int[2] {0x10191,0x002D},

        // Less than

        new int[2] {0x2039,0x003C},

        new int[2] {0x2329,0x003C},

        new int[2] {0x27E8,0x003C},

        new int[2] {0x3008,0x003C},

        // Greater than

        new int[2] {0x203A,0x003E},

        new int[2] {0x232A,0x003E},

        new int[2] {0x27E9,0x003E},

        new int[2] {0x3009,0x003E},

        //Question mark

        new int[2] {0x00BF,0x003F},

        new int[2] {0x037E,0x003F},

        new int[2] {0x061E,0x003F},

        new int[2] {0x203D,0x003F},

        //^ accent

        new int[2] {0x02C4,0x005E},

        new int[2] {0x02C6,0x005E},

        new int[2] {0x0302,0x005E},

        new int[2] {0x2038,0x005E},

        new int[2] {0x2303,0x005E},

        //Pipe sign

        new int[2] {0x01C0,0x007C},

        new int[2] {0x05C0,0x007C},

        new int[2] {0x2223,0x007C},

        new int[2] {0x2758,0x007C},

        //Tilde

        new int[2] {0x02DC,0x007E},

        new int[2] {0x0303,0x007E},

        new int[2] {0x2053,0x007E},

        new int[2] {0x223C,0x007E},

        new int[2] {0xFF5E,0x007E},

        //Asterisk

        new int[2] {0x066D,0x002A},

        new int[2] {0x204E,0x002A},

        new int[2] {0x2217,0x002A},

        new int[2] {0x26B9,0x002A},

        new int[2] {0x2731,0x002A},

        //Bullets

        new int[2] {0x00B7,0x002A},

        new int[2] {0x0387,0x002A},

        new int[2] {0x2022,0x002A},

        new int[2] {0x2024,0x002A},

        new int[2] {0x2027,0x002A},

        new int[2] {0x2219,0x002A},

        new int[2] {0x22C5,0x002A},

        new int[2] {0x30FB,0x002A}

    };

 

    //Replace single characters

    for (int i = 0; i < unicodeMatrix.Length; i++)

    {

        input = input.Replace((char)unicodeMatrix[i][0], (char)unicodeMatrix[i][1]);

    }

 

    //Filter out all remaining non-ASCII characters

    RegexOptions regexOpts = RegexOptions.IgnoreCase & RegexOptions.Multiline;

    Regex regex = new Regex("[^\x20-\x7E]", regexOpts);

    return regex.Replace(input, string.Empty);

}

March 10
Hidden Flight Simulator in Google Earth

I'm a big fan of Google Earth. I used it since early Beta versions and still discovering something new.

Yesterday I found the coolest feature! The latest Google Earth contains a hidden flight simulator mode. Press Ctrl+ Alt+A and you can chose to fly SR22 or F16 from several airports around the world or right from your current view. Here is the full list of controls.

Sceenshot

Flight Sim Menu

February 15
LCD Photo Frames sold in US are infected by Chinese trojan horse

Some quotes from the article:

An insidious computer virus recently discovered on digital photo frames has been identified as a powerful new Trojan Horse from China that collects passwords for online games - and its designers might have larger targets in mind.

The initial reports of infected frames came from people who had bought them over the holidays from Sam's Club and Best Buy. New reports involve frames sold at Target and Costco, according to SANS, a group of security researchers in Bethesda, Md., who began asking for accounts of infected devices on Christmas Day.

Full article: http://www.sfgate.com/cgi-bin/article.cgi?f=/c/a/2008/02/15/BU47V0VOH.DTL&type=business

McAfee: http://vil.nai.com/vil/content/v_142518.htm

September 11
How to Save a Database Diagram as an Image.

Usually database diagrams are big. Really big. Even if you have just 5-6 tables there is a good chance that they are not going to fit on the single screen. Try to capture it with Alt+PrtScn and you’ll get only part of it. There is no option to “Save as…” image in Management Studio either. I tried to use the Snipping Tool available in Vista to take the screen capture, but it will not capture anything from “behind” the current screen. Neither did other tools I tried. Here is the simple solution:

Open your diagram in SQL Server 2005 Management Studio. Make sure the zoom is set to 100%. There is an item in the Edit menu called “Copy Diagram to Clipboard”. Evidently it copies the whole diagram as an image. Bingo! Now it’s up to you where to paste it. My personal preference is Paint.NET. It’s free and has enough functionality for a developer.

July 26
Interesting Project: Askville.com
I just got an invitation from Amazon.com to join their new project: Askville.com
Askville is a friendly gathering place where you can ask questions on any topic and 'get real answers from real people'. It's a fun place to meet others with similar interests, share your knowledge, or just enjoy reading questions and answers submitted by others. It's new, it's fun, and it's free!
It seems interesting. Kind of Twitter on steroids.
 
Askville.com
June 20
Default Vista Aero Icons Location

If you ever wondered where hi-res Aero Vista icons are, they are all in %SystemRoot%\System32\imageres.dll file, instead of %SystemRoot%\System32\shell32.dll, as it used to be in pre-vista versions of Windows.

June 20
Windows Photo Gallery white balance fix

From the day one of using Vista I was extremely annoyed with the ugly color Windows Photo Gallery rendered my pictures. That yellowish tint looked really ugly.

Before:

After:

It turned out that Windows Photo Gallery uses default monitor profile to correct the white balance, while de-facto standard for computer graphics color space is sRGB.

So, here is the way to fix it.

  1. Right-click on the desktop, select "Personalize" from the context menu.
  2. Click "Display Settings", "Advanced Settings…", and then select "Color Management" tab. Click "Color Management".
  3. For every monitor you have in the "Device" drop-down follow these steps:
    1. Select "Use my settings for this device" checkbox.
    2. Remove existing profile. (Select it and click "Remove" button).
    3. Click "Add…" button.
    4. Select "sRGB IEC61966-2.1" ICC profile and click "OK".
    5. Click "Set as Default Profile" button.
  4. Reboot.

That how it should look afterwards:

The next thing I'm trying to figure out is how to change the background of the Windows Photo Gallery to something darker…

April 26
Canon RAW Codec for Windows Vista

One of the biggest disappointments with upgrading to Windows Vista was the lack of the RAW file format support. I always shoot in RAW with my Canon cameras and got used to preview images in the browser before processing and converting them to JPEG. Here is some of my work: http://www.arkhip.com/ (redirect to http://www.pbase.com/arkhipus)

Canon has finally released their RAW codec for Windows Vista 32 bit. No words about availability for 64 bit versions.

List of supported Canon cameras:

  • EOS-1Ds Mark II
  • EOS-1D Mark III
  • EOS-1D Mark II N
  • EOS-1D Mark II
  • EOS 5D
  • EOS 30D
  • EOS 20D
  • EOS 400D DIGITAL
  • EOS DIGITAL REBEL XTi
  • EOS Kiss Digital X
  • EOS 350D DIGITAL
  • EOS DIGITAL REBEL XT
  • EOS Kiss Digital N

Go to: http://www.usa.canon.com/consumer/controller?act=DownloadIndexAct

Select "EOS (SLR) Camera Systems" category, select "Digital EOS Cameras", and then select your model and click "Go". On the next page click "Drivers / Software" link to open a pop-up page. Check "Canon RAW Codec 1.0 for Windows Vista" radio button, accept license and download the codec.

1 - 10Next