As show in this screen shot, the selected folder is not in the view. It needs to be scrolled down to view the selected folder.
Same dialog shows selected folder visible on different computer
I ran it on two computers both having windows 7. It works correctly on one but does not on 2nd. It looks something with windows environment instead some code issue? Can anyone suggest any fix?
There is no change in code. I used longer paths from different drives but results are same.
private void TestDialog_Click ( object sender, EventArgs e )
{
//Last path store the selected path, to show the same directory as selected on next application launch.
//Properties.Settings.Default.LastPath
FolderBrowserDialog dlgFolder = new FolderBrowserDialog ();
dlgFolder.RootFolder = Environment.SpecialFolder.DesktopDirectory;
dlgFolder.SelectedPath = Properties.Settings.Default.LastPath;
if (dlgFolder.ShowDialog () == System.Windows.Forms.DialogResult.OK)
{
Properties.Settings.Default.LastPath = dlgFolder.SelectedPath;
Properties.Settings.Default.Save ();
}
}
Best Answer
The fundamental problem is a poor design decision in the
FolderBrowserDialog
. First, we need to realize that theFolderBrowserDialog
is not a .NET control, but is rather theCommon Dialog
and is part of Windows. The designer of this dialog elected not to send the TreeView control aTVM_ENSUREVISIBLE
message after the dialog is displayed and an initial folder is selected. This message causes a TreeView control to scroll so that the currently selected item is visible in the window.So, all we need to do to fix this is to send the TreeView that is part of the
FolderBrowserDialog
theTVM_ENSUREVISIBLE
message and everything will be great. Right? Well, not so fast. This is indeed the answer, but there some things standing in our way.First, because the
FolderBrowserDialog
is not really a .NET control, it does not have an internalControls
collection. This means that we can't just find and access the TreeView child control from .NET.Second, the designers of the .NET
FolderBrowserDialog
class decided to seal this class. This unfortunate decision prevents us from deriving from it and overriding the window message handler. Had we been able to do this, we might have tried to post theTVM_ENSUREVISIBLE
message when we got theWM_SHOWWINDOW
message in the message handler.The third issue is that we can’t send the
TVM_ENSUREVISIBLE
message until the Tree View control actually exists as a real window, and it does not exist until we call theShowDialog
method. However, this method blocks, so we won’t have the opportunity to post our message once this method is called.To get around these issues, I created a static helper class with a single method that can be used to show a
FolderBrowserDialog
, and will cause it to scroll to the selected folder. I manage this by starting a shortTimer
just prior to calling the dialogue'sShowDialog
method, and then tracking down the handle of theTreeView
control in theTimer
handler (i.e., after the dialogue is displayed) and sending ourTVM_ENSUREVISIBLE
message.This solution is not perfect because it depends on some prior knowledge about the
FolderBrowserDialog
. Specifically, I find the dialogue using its window title. This will break with non-English installations. I track down the child controls in the dialogue using their dialogue Item IDs, rather than title text or class name, because I felt this would be more reliable over time.This code has been tested on Windows 7 (64 bit), and Windows XP.
Here is the code: (You may need:
using System.Runtime.InteropServices;
)