CheckBox Control Acts as Toggle Button

We needed to use common Windows Forms control to show a simple toggle style small text box. We firstly wanted to use Textbox control, but later we found Textbox control is not good for toggling.

Then we found we can use Checkbox control, Checkbox provides a feature named Appearance, we can set its Appearance as a button:

Like the following code:

CheckBox toggleBtn = new CheckBox();
toggleBtn .Appearance = Appearance.Button;
toggleBtn .TextAlign = ContentAlignment.MiddleCenter;
toggleBtn .MinimumSize = new Size(25, 25); //set mini size

It worked great!

Windows Forms Listview Control Columns Header not Shown

When you use Windows Form Listview control, you will see a strange problem: you added columns, but the columns can not showing up in the designer panel in Visual Studio.

This is from Microsoft design: they set default Listview control view property to LargeIcon, maybe they think ListView control is not like regular DataGridView control, the view should be use Icon showing style?

Continue reading “Windows Forms Listview Control Columns Header not Shown”

WPF and Windows Form Integration Application Localization

We have a Windows From application to load WPF modules, due to Microsoft programming guide, they called this kind of application as WPF and Windows Form integration application.

What ever, we now need the integration application to support multiple cultures, is localization.

Let’s start from a simple application, a Windows Form application load a WPF control.

Continue reading “WPF and Windows Form Integration Application Localization”

Windows Form FlowLayoutPanel Memory Leak ?

There were not only one time, and there were lots of programmer who used Windows Form FlowLayoutPanel control got the memory leak issues.

In our case, we used FlowLayoutPanel control wrapped multiple user controls which include PictureBox controls and other controls. we need constantly clear the FlowLayoutPanel and add new user controls. We found the memory leak, looks like the FlowLayoutPanel did not “clear”, finally we found when we load FlowLayoutPanel clear method, the user controls seems still in the memory (with PictureBox maybe).

So we tried the manually load Dispose method before clear. like the following:

foreach (Control ctrl in flowlayoutpanal1.Controls) { ctrl.Dispose(); 

} flowlayoutpanal1.Controls.Clear();

Also, we added other code in User Control’s dispose method to dispose any 3rd party controllers which are not Microsoft Windows Form controllers.

However, we found the memory leak issue still there, we did not fix it.

Actually, in above code, we made a classic .NET error: when control disposed, it also was removed from its parent control. so the children controls of flowlayoutpanel1 always changed. so we should not use “foreach” for a changed list.

So now you know how you should dispose the children controls, the following is a sample, use For loop, and NOT from beginning, but from end of the list:

for(int i = flowlayoutpanel1.Controls.Count-1; i >= 0; --i)
{ 
   var ctl = flowlayoutpanel1.Controls[i];
    ctl.Dispose();
}

Windows Form Application: Stopped Working Due to Problem Event Name CLR20r3

There was a windows form application based on .NET 4.0 and Visual Studio 2010, it was working well on a PC which we developed it. when we move its debug folder which including generated executable files, it crashed (We use Windows 7):

CLR20r3Error0

We expanded “Show problem details” button and saw the following information:

Description:
  Stopped working

Problem signature:
  Problem Event Name:    CLR20r3
  Problem Signature 01:    cnserver.exe
  Problem Signature 02:    1.0.0.0
  Problem Signature 03:    4f16e189
  Problem Signature 04:    CnServer
  Problem Signature 05:    1.0.0.0
  Problem Signature 06:    4f16e189
  Problem Signature 07:    225
  Problem Signature 08:    6
  Problem Signature 09:    System.IO.FileNotFoundException
  OS Version:    6.1.7600.2.0.0.256.48
  Locale ID:    1033

Read our privacy statement online:
  http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409

If the online privacy statement is not available, please read our privacy statement offline:
  C:\Windows\system32\en-US\erofflps.txt

Due to above information, sees our application missed some files which should be included in output folder. but what the files are ?

Obviously we have some unhandled exceptions in our program due to the error message and the crash, we can not see apparent reason, so we should add the missed exceptions handler.

For example:  AppDomain.CurrentDomain.UnhandledExceptio

Then we add the handlercode into the application startup process, In our case, we add the code in Program.cs file, see the following code, you will see what code you should add into your Program.cs:

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);


            Application.Run(new Form1());
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            MessageBox.Show(((Exception)e.ExceptionObject).Message, "Unhandled UI Exception");

        }

        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");

        }
    }

After we added above code, we ran our application again, and got a popup window like the following:

CLR20r3Error1

So then we know the missed the file is about “Microsoft.VisualBasic.PowerPacks.Vs”, it is a library file. it missed on the new PC, so we just “include” the dll file to output folder in Visual Studio 2010, then our application can work on other PCs.

Custom Microsoft Chart Control Zoom Reset Button

After you zoom in the Microsoft Chart control. you will see X scroll bar and Y scroll bar which you can scroll the view. Also, you can see two small icons beside the scroll arrow button on scroll bars, the one is on X scroll bar, another one is on Y scroll bar. They are zoom reset buttons.

By default, the zoom reset button only reset one Axis zoom and reset the zoom level to previous scale. When you try to click them, you can see the zoom level reset step by step.

msChartReset00

In some cases, you do not want to the zoom reset works like its default way, but you want the zoom reset just “click one time” and reset the zoom rate to its original level. and also, you might just want one zoom reset button in your UI.

About how to hidden one of the tow zoom reset buttons is simple. it is only one line of code:

msChartReset01

 chartAreaTrending.AxisY.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;

The SmallScroll Style indicate there is no ResetZoom button displayed.

The custom the zoom reset button event:

private void chartTrending_AxisScrollBarClicked(object sender, ScrollBarEventArgs e)
{
   if (e.ButtonType == ScrollBarButtonType.ZoomReset)
   {
       e.IsHandled = true;
       this.chartAreaTrending.AxisX.ScaleView.ZoomReset(0);
       this.chartAreaTrending.AxisY.ScaleView.ZoomReset(0);

       this.chartAreaTrending.CursorX.SelectionStart = double.NaN;
       this.chartAreaTrending.CursorY.SelectionEnd = double.NaN;
    }
}

Force Windows Form Application to Run As Administrator on Windows 7

If you are using Windows 7 or Windows Vista, or Windows Server 2008, you should know the UAC (User Account Control), this is one of significant differences between Windows XP and the newer Windows System.

“User Account Control (UAC) determines the privileges of a user. If you are a member of the Built-in Administrators group, you are assigned two run-time access tokens: a standard user access token and an administrator access token. By default, you are in the standard user role. When you attempt to perform a task that requires administrative privileges, you can dynamically elevate your role by using the Consent dialog box. The code that executes the IsInRole method does not display the Consent dialog box. The code returns false if you are in the standard user role or in the Built-in Administrators group. You can elevate your privileges before you execute the code by right-clicking the application icon and indicating that you want to run as an administrator.” – From MSDN.

When you build a Windows Form application using C#, your application will not run as administrator by default. Then if your application need more permissions just like an Administrator, you might get problem since your application can not access enough resources;

The simplest solution is disabling the UAC on your Windows system. About how to disable UAC, we will discuss in another time, this time we do not want to talk about more about this since disabling UAC for a windows system is not recommended.

The normal and the best solution is using manifest file.

Open your application in Visual Studio 2010, Right click the project and add a new item, choose “Application Manifest File”:

manifest00

Now you can see a new file named “app.manifest” is added under Properties folder:

manifest01

When you open app.manifest file, you can see there are some sample settings have been already there, for example:

      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC Manifest Options
            If you want to change the Windows User Account Control level replace the 
            requestedExecutionLevel node with one of the following.

        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            Specifying requestedExecutionLevel node will disable file and registry virtualization.
            If you want to utilize File and Registry Virtualization for backward 
            compatibility then delete the requestedExecutionLevel node.
        -->

      </requestedPrivileges>

What we should do is just remove comment for this line:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

manifest02

When you done above steps, rebuild your windows form application, then every time when you try to restart your application, you will be asked whether you need to run as administrator.

 manifest03

Arrow keys can not be captured in KeyDown event ?

In Windows Forms, If you write a KeyDown event method for some keys, such as arrow keys, you might find it doesn’t work, but for other keys like A,B,C,D… it work.

The reason is that some Windows Form controls ignore the key press from the TAB key, RETURN key, ESC key, and arrow keys by default, these keys are not considered input keys.

For example,when you press arrow keys on a button, it will causes the focus to move to previous or next control, now the arrow keys are navigation keys, so you can not capture them in KeyDown event.

This rule is not for button control, it also for some other controls, includes User controls.

The solution is using PreviewKeyDown event, not KeyDown event; Or still use KeyDown event, but should set the IsInputKey property to true in PreviewKeyDown; and you have to know the focus will no longer move to the previous or next control.

For example, we have a user control in our project. Before we used code like following:

private void vectShapes_KeyDown(object sender, KeyEventArgs e)
{
    bool eleChanged = false;

    int x, y;

    x = y = 0;

    switch (e.KeyCode)
    {
        case Keys.Left:
        case Keys.A:
            x = -1;
            doMoveEle(x, y);
            eleChanged = true;
            break;
        case Keys.Right:
        case Keys.D:
            x = 1;
            doMoveEle(x, y);
            eleChanged = true;
            break;

        case Keys.Up:
        case Keys.W:
            y = -1;
            doMoveEle(x, y);
            eleChanged = true;
            break;

        case Keys.Down:
        case Keys.S:
            y = 1;
            doMoveEle(x, y);
            eleChanged = true;
            break;
    }

    ...
}

Of course the arrow keys could not work, now we changed to the following:

Way 1: Simply set IsInputKey to true in PreviewKeyDown event, and keep all logic code in KeyDown event:

private void VectShapes_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.Down:
        case Keys.Up:
        case Keys.Right:
        case Keys.Left:
            e.IsInputKey = true;
            break;
    }
}

Way 2: Move all logic code from KeyDown event to PreViewKeyDown event:

private void VectShapes_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    bool eleChanged = false;

    int x, y;

    x = y = 0;

    switch (e.KeyCode)
    {
        case Keys.Left:
        case Keys.A:
            x = -1;
            doMoveEle(x, y);
            eleChanged = true;
            break;
        case Keys.Right:
        case Keys.D:
            x = 1;
            doMoveEle(x, y);
            eleChanged = true;
            break;

        case Keys.Up:
        case Keys.W:
            y = -1;
            doMoveEle(x, y);
            eleChanged = true;
            break;

        case Keys.Down:
        case Keys.S:
            y = 1;
            doMoveEle(x, y);
            eleChanged = true;
            break;
    }

    ...
}

Scrolling Stuck in Microsoft Chart Control

We have a windows form project which used Microsoft Chart Control. The Axis X is DateTime type, Axis Y are double values.

We need zoom in/out feature and scroll feature, so we have already the following initial code:

chartAreaTrending.CursorX.Interval = 0;
chartAreaTrending.CursorY.Interval = 0;
chartAreaTrending.CursorX.IsUserSelectionEnabled = true;
chartAreaTrending.CursorY.IsUserSelectionEnabled = true;
chartAreaTrending.AxisX.ScaleView.Zoomable = true;
chartAreaTrending.AxisY.ScaleView.Zoomable = true;
chartAreaTrending.CursorX.SelectionColor = Color.DarkGray;
chartAreaTrending.CursorY.SelectionColor = Color.DarkGray;
chartAreaTrending.AxisY.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
this.chartAreaTrending.AxisX.IntervalType = DateTimeIntervalType.Minutes;
this.chartAreaTrending.AxisX.LabelStyle.Format = "yyyy-MM-dd HH:mm";


But later we found the scrolling function on Axis X stuck, we could not scroll but just sometimes jumped very long step.

mschartScroll00

The problem should be from the chart area zoom, firstly we tried to add the following code about ScaleView of AxisX:

this.chartAreaTrending.AxisX.ScaleView.MinSize = 0;
this.chartAreaTrending.AxisX.ScaleView.MinSizeType = DateTimeIntervalType.Minutes;
this.chartAreaTrending.AxisY.ScaleView.MinSize = 0;

But it still did not work.

Finally we featured out we should set value for SmallScrollSize and SmallScrollSizeType.

mschartScroll01

So we need to add the following code to implement:

this.chartAreaTrending.AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Minutes;
this.chartAreaTrending.AxisX.ScaleView.SmallScrollSizeType = DateTimeIntervalType.Minutes;
this.chartAreaTrending.AxisY.ScaleView.SmallScrollMinSize = 0.01;
this.chartAreaTrending.AxisY.ScaleView.SmallScrollSize = 0.01;

Windows Program Compatibility Assistant

When we ran a Windows Form program and after we closed it, we got a message windows below:

“Windows detected that this program did not run correctly

To try and fix the problem, Windows has applied compatibility settings to this program, Windows will use these settings the n3ext time you run the program

If you noticed that this program didn’t run correctly, try running the program again

Location: C:\Program Files(x86)\Micro…\devenv.exe”

prgCompatAssistant00

What is the Program Compatibility Assistant?

The Program Compatibility Assistant detects known compatibility issues in older programs. After you have run an older program in this version of Windows, it notifies you if there is a problem and offers to fix it the next time you run the program. If the compatibility issue is serious, the Program Compatibility Assistant might warn you or block the program from running. If that happens, you’ll have the option to check online for possible solutions.

But don’t worry the Windows Program Compatibility will NOT modify the program, it just change something in Windows so that Windows can run the program correctly.