Keeping a modeless window accessible from a modal (dialog) window

In a C# WinForms application I was working on, users were effectively working with two more or less independent windows: one they worked in, and another that showed documents and other info they need to do that work. The problem was that when they were in a dialog, for example one to assist in creating a new object, the window holding the documents with info on the object was not accessible because the dialog is modal.

You can have the dialog take ownership of the document window, but that means also it will always be on top of it, which would be inconvenient.

So I borrowed a trick from my Delphi days that I found here. You only need to do a small Windows API call from your code. I added this code to utility class called FormsUtil, but you could of course put it anywhere that’s convenient to you.


[DllImport("user32.dll")]
private static extern bool EnableWindow(IntPtr hwnd, bool bEnable);

public static bool EnableWindow (Form form, bool enable) {
    return EnableWindow(form.Handle, enable);
}

This allows you to, in the dialog form, attach an event handler to the Shown event:

private void NewObjectForm_Shown(object sender, EventArgs e) {
    if (this.Modal) {
        var viewer = GetReferenceToDocumentViewerForm();
        FormsUtil.EnableWindow(viewer, true);
    }
}

Now the document viewer window is accessible from the “new object” dialog.

Tip: be careful if you ever choose to use EnableWindow(formX, false). It will disable that form completely, including not being able to close it.

Respond to a click on the background of a listview

A typical list view, in this case from Explorer. Items are unselected when you click in an empty area.

I have a list view in a project that i use to show properties for objects in a tree-like hierarchy, much like the windows explorer. When a user clicks an item, its properties are shown. That wasn’t so hard, just handle the Click event.

When a user clicks next to an item or in an empty space of the list view, the item is automatically unselected in the view. The list view does this for you. I wanted to use this event, to show the properties of the parent object of the items in the view. But kind of to my surprise no Click event was fired when that happened.

In fact, I couldn’t find another event that really did what I wanted. Some suggested to use the ItemSelectionChanged event, like in this somewhat related problem, but that would require me to track all pairs of selection/unselection and to only respond when an item was unselected, after which no selected event would happen. I figured it would be too tricky (and too much work) to get that right.

So I cooked up another solution. It’s no rocket science, but it works exactly as I would like it to. Here’s how you do that… Lees meer over dit bericht

Jet OleDB 4.0 provider not registered on the local computer

I have a C# WinForms program that attempts to import some data from Excel into a SQL Server database using the Ole DB provider. Today the import suddenly failed with an error message saying that the Jet Ole DB provider was not registered on the local computer.

InvalidOperationException: Jet OleDB 4.0 provider not registered on the local computer

Well, I was pretty sure that it was. So what was wrong then?

Turned out that the Configuration Manager accidentally got reset to “Any CPU” setting. I have an x64 machine on which that leads to running the application in 64-bit mode, in which there is indeed no Jet OleDB provider available (and no Edit-and-Continue either, among other things…).

Setting the target platform to compile to x86 immediately solved the problem.

Open a .cs file in code view instead of winforms designer

This bugged me for a while. It didn’t bug me enough to spend much time looking for it, but every once in a while I would give it a try and then I’d give up again. The problem? When double-clicking a file in the solution explorer, it would open in the windows forms designer. I wanted it to open in code view, but couldn’t find it anywhere in the extensive Visual Studio Options screen. For HTML-view, there was an option, but not for windows forms files. Huh?

That was because I was looking in the wrong place. Right click a .cs file and choose “Open with”. Then select “CSharp editor” and click “Set default”. Duh.

The easy-to-find option, in a really obvious place

Select all text in a textbox when the user clicks to focus

A tiny patch of code can sometimes save your users a lot of time. In a project I was working on, I used a lot of small textboxes to have the user input small numeric values. (Actually the textbox was a part of a kind of self-constructed NumericUpDown, but that’s another story.) Watching a tester work with the program, I saw him often clicking in the box and then starting typing his numbers, becoming increasingly annoyed that the numbers would be inserted at the position he clicked instead of overwriting the number that was already there.

Selecting all text in a box is nice behavior when you Tab into it, but in general I don’t like it for clicking in the box, because I expect the caret to be where I put it. There are exceptions to that: the browser address bar is one of them and that makes sense, because you more often than not want to overwrite the entire address instead of inserting or modifying parts. And, come to think about it, because these were just small numbers (up to 4 positions), I had to agree with the tester that it if you want to change a number, it would be a lot easier to just type over it, than it would be to start inserting or modifying digits. Lees meer over dit bericht

WinForms ComboBox does not always fire SelectionChangeCommitted

Today I ran into the problem that a ComboBox in my project did not always fire the SelectionChangeCommitted event when I expected it to. To be specific, if a user dropped down the list, used the arrow keys to move to an item, and then TABbed to the next control, the new item would be selected but the event never fired. This was a problem for me, because I relied on this event to filter the items in the next control, depending on the selection made in the first.

Some googling quickly learned that this was a known problem with the ComboBox, although the thread is about the SelectedIndexChanged event, it appears the same error prevents SelectionChangeCommitted from behaving as expected. As user comecme in that thread pointed out, there even was a knowledgebase item including a workaround available from Microsoft. But as he also points out… the workaround does not work.

So I decided to cook up my own solution. This would involve subclassing the Combobox to change the behavior I needed. I had one advantage, I was already using a subclassed ComboBox in all places I needed this behavior, so no Find+Replace was required to replace all standard ComboBoxes with my own.

To this subclassed combobox (named CatalogComboBox) I added the following code:

private CatalogComboItem keepSelection;

protected override void OnEnter(EventArgs e) {
  keepSelection = this.SelectedItem;
  base.OnEnter(e);
}

protected override void OnLeave(EventArgs e) {
  if (this.SelectedItem != keepSelection)
    OnSelectionChangeCommitted(EventArgs.Empty);
  base.OnLeave(e);
}

protected override void OnSelectionChangeCommitted(EventArgs e) {
  base.OnSelectionChangeCommitted(e);
  keepSelection = this.SelectedItem;
}

(I used CatalogComboItem because my combo items where typed as such, but you can always use object.) It’s a not spectacularly elegant or high-tech solution, but it works like a charm.

The case of the Visual Studio blank properties window

I experienced the strangest thing with my installation of Visual Studio 2008 last Friday. In the middle of developing a Windows Forms application, I noticed that the Properties window had stopped working. It was still there, just blank, and so was the dropdown above it where the components usually reside.

Update 19-12: This blog post will be revised soon. I have since experienced this same error under different conditions which had a different solution.

Update 20-12: This blog post is superseeded by this one. I have now found a generic strategy to follow if this situations occurs. The solution presented below was probably a one-time fix that will most probably not help you. Please read the new article.

Blank Properties window in Visual Studio

This was not just with the current file, but for all files in my solution. It would not even display the mainly informal properties of the current file selected in the Solution Explorer. Closing the solution and re-opening it did not help. Hiding the properties window and re-showing it did not help. Google led me to several suggestions, most of them telling me to execute a command in the Visual Studio command prompt (devenv /setup) would fix things. Nope, not for me. Starting VS in safe mode to eliminate plugins. Still blank. Even other solutions I opened now had a blank properties window. Oh dear. I was now getting worried that I broke something very serious in my VS installation.

Lees meer over dit bericht