Blog

posts tagged with framework

Hooray!

0 Comments
By Fons Sonnemans, 19-2-2006

I have just received mail from Pearson VUE informing me that have passed the Beta Exam 70-528 TS: Microsoft .NET Framework 2.0 - Web-Based Client Development (called 71-528 while it's in Beta). I also received a free Voucher for a next exam, thanks guys.

On Friday I will try the Beta Exam 70-551 UPGRADE: MCAD Skills to MCPD Web Developer by Using the Microsoft .NET Framework. One week later I will try the Beta Exam70-552 UPGRADE: MCAD Skills to MCPD Windows Developer by Using the Microsoft .NET Framework . Wish me luck.

Tags: CSharp, Framework

Microsoft has put my 'Dual List' .NET Magazine article online!

0 Comments
By Fons Sonnemans, 9-4-2005
 

Microsoft has put my Visueel programmeren met .NET: Dual List Control article online. It is published in the .NET Magazine #8 and it is free for Dutch developers.
They didn't publish the sourcecode (yet) but you can download it from my own site. The aricle is in Dutch. You can find an (old) English version of this article here. An even more advanced implementation that also supports Drag & Drop can be found here.

WaitCursor

0 Comments
By Fons Sonnemans, 10-2-2005

For a long time I thought that I only had to set the Cursor.Current to a WaitCursor before a long running operation, the .NET runtime would reset it back to the Default cursor. Turns out that this is only true when the mouse is moved. Bummer.

// Cursor.Current are automatically reset to Default when the
// mouse is moved and the application is idle!
Cursor.Current = Cursors.WaitCursor;

The solution for this problem is very easy. I created a helper class called WaitCursor which set the Cursor.Current and restores it to the original value when it it disposed.

public sealed class WaitCursor : IDisposable {                
    private Cursor _prev;

    public WaitCursor() {
        _prev = Cursor.Current;
        Cursor.Current = Cursors.WaitCursor;
    }

    public void Dispose() {
        Cursor.Current = _prev;
    }
}

I create the instance of the WairCursor class inside a using statement. This will automatically call the Dispose() method when it goes out of scope.

using (new WaitCursor()) {
    // long running operation, for example:
    System.Threading.Thread.Sleep(1000);
}

Afterwards I did some searching around on the web. Turns out I'm not the first to come up with this solution. Charlie Poole already posted it a few years ago. Another bummer.

Dispose Modal WinForm Dialogs

0 Comments
By Fons Sonnemans, 12-12-2004

There is a difference in disposing Modal and Non-Modal forms. In a training I gave last week I noticed that even experienced developers didn't know that Modal Dialogs don't dispose automatically, Non-Modal do.

private void buttonShowNonModalForm(object sender, System.EventArgs e) {
    new TestForm().Show();
}

private void buttonShowModalDialog(object sender, System.EventArgs e) {
    new Form2().ShowDialog();
}

The solution to this problem is very simple by creating the Form instance within a using block. This will dispose the Form when it is closed.

private void buttonShowModalDialog(object sender, System.EventArgs e) {
    using (TestForm f = new TestForm()) {
        f.ShowDialog();
    }
}

An alternative solution uses a try/finnaly. Personally I prefer the previous, it is easier to read and write.

private void buttonShowModalDialog(object sender, System.EventArgs e) {
    TestForm f = null;
    try {
        f = new TestForm();
        f.ShowDialog();
    } finally {
        if (f != null) {
            f.Dispose();
        }
    }
}

The following solution isn't correct. You might think it is, but it isn't. The Dispose will not be executed when an Exception is thrown from within the ShowDialog().

private void buttonShowModalDialog(object sender, System.EventArgs e) {
    TestForm f = new TestForm();
    f.ShowDialog();
    f.Dispose();
}

DualList Drag & Drop Component

0 Comments
By Fons Sonnemans, 16-9-2004

Introduction

I have written an article two years ago with the title 'WinForm DualList Component'. In this article I mentioned the desire to extend the DualList component with Drag & Drop support. Finally it's done. Not by extending the original DualList component but by creating an new DualListDragDrop component (reason: cohesion).

Programming Drag & Drop (D&D) between listboxes is quite difficult. It requires at least 60 lines of code for every two listboxes. Therefore not many application support D&D. This component eliminates need of writing the code. You only have to set properties on it. Making it easy to support D&D in your applications.

DualListDragDrop Component

The DualListDragDrop component is a component which can be dropped in the 'component tray' of a windows Form. You therefore first have to add it to the Toolbox of Visual Studio.NET. This can easily be done by dragging   ReflectionITWinFormComponents.dll assembly from an normal Windows Explorer and dropping it on the Toolbox. All controls and components from the assembly will be added to the Toolbox. You can create an separate Tab for it if you want.

For each D&D direction you must add DualListDragDrop component to you Form. In this example three. For each component you have to set the '(Name)', 'ListBoxFrom' and 'ListBoxTo' properties.

 

You can use the DualListDragDrop component to reorder the position of the items in a ListBox by selecting the same 'From' and 'To' ListBox.

Action property

You can choose from three values for the Action property: Move, Copy and MoveAndCopy. The MoveAndCopy will normally move an item. You can copy the item by pressing the Ctrlkey while initiating the D&D operation.

DropIndicator property

The DropIndicator can be set to 'True' which means you will get a red dotted line indicating where the item will be placed when you drop the item. It supports scrolling the listbox up and down when you move your mouse over the first or last visible item. The item will be added to the bottom of the list when the property is set to 'False'. The color of the line can be selected using the IndicatorColor property.

Conclusion

The DualList and DualListDragDrop components are easy solutions for difficult features. It takes care of all logic needed to move and or copy items from one listbox to another. Use them in your own applications, they are free.

Hopefully this article will encourage more people to make use of the component architecture in their own applications.

Any suggestions and feedback for improving this article is most welcome. Send your suggestions and feedback to Fons.Sonnemans@reflectionit.nl

License Information

The ReflectionITWinFormComponents assembly is free for use in commercial or private applications. However, you may only redistribute this in its compiled form (modified or unmodified), you may not redistribute the source or modified source. When using it, please include the line "ReflectionITWinFormComponents - Copyright Reflection IT - http://www.reflectionit.nl/" reference in either the about or in the documentation. This will help me out and allow me to continue to provide you with free controls.

ToolboxBitmap workaround

0 Comments
By Fons Sonnemans, 3-9-2004

I have found a solution for a problem which I had for a long time. I was unable to set the ToolboxBitmap attribute for a component using the (type, string) constructor. I found the solution for this problem (using an internal ResFinder class) on www.bobpowell.net. This site has also some other Windows Forms Tips and Tricks. Great!

System.Collections and System.Collections.Specialized

0 Comments
By Fons Sonnemans, 8-3-2004

This table gives you an overview of all collections in the System.Collections and System.Collections.Specialized namespaces.

Class Key Value Remarks
System.Array   ? Predefined size, used for passing data around.
ArrayList   Object Easy to work with, provides basic collection functionality and can easily be converted to an Array.
BitArray   Boolean
Manages a compact array of bit values, which are represented as Booleans
CollectionBase   ? Abstract base for building your own collection classes.
DictionaryBase Object ? Abstract base for building your own collection classes using a key-value pair.
HashTable Object Object Provides high performance access to items in the key-value pair collection, by a specific key.
Queue   Object Implements the FIFO mechanism.
ReadOnlyCollectionBase   Object Abstract base for building your own read-only collection classes.
SortedList Object (sorted) Object Provides access to items in the collection by a specific key or an index (GetByIndex(int)).
Stack   Object Implements the LIFO mechanism.
Specialized.HybridDictionary
Object Object Uses internally a ListDictionary class when the collection is small, and switches automatically to a Hashtable class when the collection gets large.
Specialized.ListDictionary Object Object Is designed to be used for collections with 10 or less items, while the Hashtable is designed to contain more items.
Specialized.NameObjectCollectionBase String ? Abstract base for building your own collection classes using a key-value pair.
Specialized.NameValueCollection String (sorted) String NameValueCollection class is the strong type equivalent of the SortedList class, for the String class.
Specialized.StringCollection   Object Strongly typed ArrayList for the String class.
Specialized.StringDictionary String String Strongly typed Hashtable for the String class, not sorted.

Read also Jan Tielens article on the MSDN Belux website.

EventsHelper using Fire and Forget

0 Comments
By Fons Sonnemans, 7-3-2004

I have used the EventsHelper class to fire events asynchronical. I came across this class in the TechEd 2003 presentation C# Best Practices from Eric Gunnerson and Juval Löwy. Today I noticed a bug. The FireAsync() method uses the 'Fire and Forget' pattern incorrectly.

The 'Fire and Forget' pattern is used when the return value and returned parameters of the call are not required, and when there is no need to synchronize with the asynchronously executing method. In this case, the caller simply needs to call BeginInvoke, passing any normal and ref parameters, and null for the callback and asyncState.

This has been a commonly used pattern. However, there has been a documentation change in version 1.1 of the .NET Framework that has big ramifications for this technique of making async calls. The documentation now states that EndInvoke must be called for a corresponding BeginInvoke--otherwise Microsoft say they may now, or in the future, leak resources. It appears that no resources are leaked under version 1.0 of the framework; however, with this type of warning in place, it is recommended that a call to EndInvoke be made even if the return values of an async call are not required.

It is relatively straightforward to create a helper class that handles this for you--one example I found here.

public class AsyncHelper {

    delegate void DynamicInvokeShimProc(Delegate d, object[] args);

    static DynamicInvokeShimProc dynamicInvokeShim = new
        DynamicInvokeShimProc(DynamicInvokeShim);

    static AsyncCallback dynamicInvokeDone = new
        AsyncCallback(DynamicInvokeDone);

    public static void FireAndForget(Delegate d, params object[] args) {
        dynamicInvokeShim.BeginInvoke(d, args, dynamicInvokeDone, null);
    }

    static void DynamicInvokeShim(Delegate d, object[] args) {
        d.DynamicInvoke(args);
    }

    static void DynamicInvokeDone(IAsyncResult ar) {
        dynamicInvokeShim.EndInvoke(ar);
    }
}

My improved EventsHelper class now looks like this:

public class EventsHelper {

    public static void FireAsync(Delegate del, params object[] args) {
        if (del == null) {
            return;
        }
        Delegate[] delegates = del.GetInvocationList();
        AsyncFire asyncFire;
        foreach (Delegate sink in delegates) {
            asyncFire = new AsyncFire(InvokeDelegate);
            AsyncHelper.FireAndForget(asyncFire, sink, args);
        }
    }

    delegate void AsyncFire(Delegate del, object[] args);

    [OneWay]
    static void InvokeDelegate(Delegate del, object[] args) {
        del.DynamicInvoke(args);
    }

    public static void Fire(Delegate del, params object[] args) {
        if (del == null) {
            return;
        }
        Delegate[] delegates = del.GetInvocationList();
        foreach (Delegate sink in delegates) {
            try {
                sink.DynamicInvoke(args);
            }
            catch {}
        }
    }
}

DateDiff() function in C#

4 Comments
By Fons Sonnemans, 11-2-2004

I have written the following DateDiff() function in C#. VB.NET users already had it using the Micrsoft.VisualBasic.dll assembly. Now you can use it without referencing this 'ugly' extra assembly.

using System;


namespace ReflectionIT.System {

    public enum DateInterval {
        Year,
        Month,
        Weekday,
        Day,
        Hour,
        Minute,
        Second
    }

    public class DateTimeUtil {

        public static long DateDiff(DateInterval interval, DateTime date1, DateTime date2) {

            TimeSpan ts = date2 - date1;

            switch (interval) {
                case DateInterval.Year:
                    return date2.Year - date1.Year;
                case DateInterval.Month:
                    return (date2.Month - date1.Month) + (12 * (date2.Year - date1.Year));
                case DateInterval.Weekday:
                    return Fix(ts.TotalDays) / 7;
                case DateInterval.Day:
                    return Fix(ts.TotalDays);
                case DateInterval.Hour:
                    return Fix(ts.TotalHours);
                case DateInterval.Minute:
                    return Fix(ts.TotalMinutes);
                default:
                    return Fix(ts.TotalSeconds);
            }
        }

        private static long Fix(double Number) {
            if (Number >= 0) {
                return (long)Math.Floor(Number);
            }
            return (long)Math.Ceiling(Number);
        }
    }
}


Integrate NDoc HTML Help in VS.NET

0 Comments
By Fons Sonnemans, 30-12-2003

Download NDocSample.zip

Introduction

NDoc 1.2 generates class libraries documentation from .NET assemblies and the XML documentation files generated by the C# compiler. NDoc uses add-on documenters to generate documentation in several different formats, including the MSDN-style HTML Help format (.chm), the Visual Studio .NET Help format (HTML Help 2), and MSDN-online style web pages.

This article explains the four steps to take in order to integrate the HTML Help 2 file you generated into Visual Studio.NET.

  1. Comment the Library using XML documentation tags
  2. Create HTML Help 2 using NDoc
  3. Registering the Help File using H2Reg
  4. Include Help Collection to VSCC

Step 1: Comment the Library using XML documentation tags

I have created a sample library with two classes Employee and EmployeeCollection. These classes are documented using the XML documentation tags (///). The assembly is named ReflectionIT.NDocSample.

using System;

namespace ReflectionIT.NDocSample
{
    /// <summary>
    /// Employee class used to demonstrate NDoc and Visual Studio.NET integration.
    /// </summary>
    /// <example>
    /// Some sample:
    /// <code>
    /// Employee emp = new Employee("Jim", 4000);
    /// emp.RaiseSalary();
    /// Console.WriteLine(emp.GetYearSalary);</code>
    /// </example>
    public class Employee
    {
        privatestring_name;
        privateint_salary;

        /// <summary>
        /// Initializes a new instance of the Employee class with a name and salary.
        /// </summary>
        /// <param name="name">The name of the employee</param>
        /// <param name="salary">The salary of the employee</param>
        public Employee(stringname, intsalary)
        {
            this.Name = name;
            this.Salary = salary;
        }

        /// <summary>
        /// Gets or sets the name of the employee.
        /// </summary>
        publicstring Name {
            get{return this._name;}
            set{this._name= value;}
        }

        /// <summary>
        /// Gets or sets the salary of the employee.
        /// </summary>
        publicint Salary {
            get{return this._salary;}
            set{this._salary= value;}
        }

        /// <summary>
        /// Returns the year salary for the employee using 12 months
        /// </summary>
        /// <returns>The year salary</returns>
        publicvirtualint GetYearSalary() {
            return Salary *12;
        }

        /// <summary>
        /// Raise the salary with 10%
        /// </summary>
        publicvirtualvoid RaiseSalary() {
            Salary += Salary *10/100;
        }
    }
}

The assembly is named ReflectionIT.NDocSample. I have set the name of the xml file in which the documentation comments are processed to ReflectionIT.NDocSample.xml. Make sure this is the same name as the assembly otherwise IntelliSense will not work correctly. Don't forget to compile the assembly; this will create the xml file.

Step 2: Create HTML Help 2 using NDoc

NDoc comes with a GUI front end (NDocGUI.exe) and a console application (NDocConsole.exe). I have used the NDocGui to create a NDoc project for my NDocSample library. You can easily do this using the 'New from Visual Studio Solution...' menu option.


Next you have to set the Documentation Type to 'HtmlHelp2'. I have also changed some extra properties like: CopyrightHref, CopyrightText, HtmlHelpName and Title.

Then you are ready to build the help file. Before you can do this you have to install Microsoft Html Workshop and Microsoft Visual Studio .NET Help Integration Kit (VSHIK2003). You build the help file using the Documentation, Build menu option (Ctrl+Shift+B). The result is an ReflectionIT.NDocSample.chm help file which NDoc converted to compiled Html Help.

Step 3: Registering the Help File using H2Reg

I have used H2Reg to register the NDocSample help file. H2Reg.exe is a small utility (177K), that allows you to register MS Help 2.x Collections: Namespaces, Titles, Plug-ins, and Filters without using MSI (Microsoft Installer).

To use H2Ref you have to create an ini file in which you describe what you want to register. Below you see the H2Reg_cmd.ini file I used to register the NDocSample help file.


; - - - - - - - Register -r switch

[Reg_Namespace]
;<nsName>|<nsColfile>|<nsDesc>
ReflectionIT.NDocSample|ReflectionIT.NDocSample.HxC|ReflectionIT NDocSample

[Reg_Title]
;<nsName>|<TitleID>|<LangId>|<HxS_HelpFile>|<HxI_IndexFile>|<HxQ_QueryFile>|
;<HxR_AttrQueryFile>|<HxsMediaLoc>|<HxqMediaLoc>|<HxrMediaLoc>|<SampleMediaLoc>
ReflectionIT.NDocSample|ReflectionIT.NDocSample|1033|ReflectionIT.NDocSample.HxS|||||||

;------- UnRegister -u switch

[UnReg_Namespace]
;<nsName>
ReflectionIT.NDocSample

[UnReg_Title]
;<nsName>|<TitleID>|<LangId>
ReflectionIT.NDocSample|ReflectionIT.NDocSample|1033


I have placed this ini file together with the ReflectionIT.NDocSample.HxC and ReflectionIT.NDocSample.HxC files into a folder called Help. In this folder you have to start H2Reg with the -R switch which I have automated using the following register.bat batch file.

copy . .\Ndoc\doc\*.hxS
copy..\Ndoc\doc\*.hxC
"C:\Program Files\Helpware\H2Reg\H2Reg.exe" -r cmdfile="C:\My Documents\Visual Studio Projects\NDocSample\Help\H2Reg_cmd.ini"

Step 4: Include Help Collection to VSCC

The last step is to include the help collection in Visual Studio .NET 2003 Combined Help Collection (VSCC). Therefore you have to open the 'Visual Studio .NET Combined Help Collection Manager' page using the following hyperlink: ms-help://MS.VSCC.2003/VSCCCommon/cm/CollectionManager.htm. In this page you have to select the 'ReflectionIT.NDocSample' checkbox and click the 'Update VSCC' button.


You can change the Title attribute of HelpCollection node in the .HxC file when you want a more descriptive name.

Result

The result off all these steps is great. You will see the help file integrated into Visual Studio.NET. It is context sensitive (F1) and will also appear in the Dynamic Help.



Conclusion

The Xml documentation comments of C# are great. With NDoc and H2Reg you can generate an Html Help 2 file and integrate it in Visual Studio.NET. This will make your code libraries really (re)usable.

I haven't figured out how to add Filters and Contents (TOC). I hope to update this article soon with these options. When you find this all to difficult you should look at DocumentX which is a lot easier to use, but not for free.

Any suggestions and feedback for improving this Add-In is most welcome. Send your suggestions and feedback to Fons.Sonnemans@reflectionit.nl

All postings/content on this blog are provided "AS IS" with no warranties, and confer no rights. All entries in this blog are my opinion and don't necessarily reflect the opinion of my employer or sponsors. The content on this site is licensed under a Creative Commons Attribution By license.