|
|
Comments and Discussions
|
|
 |

|
I very lucky to find this article.
|
|
|
|

|
You're welcome
|
|
|
|

|
Hi, I've found some bug on your code in the file TreeViewFolderBrowser.cs.
In the function public virtual void RemoveDummyNode() and line number 866.
It should be "&&" instead of "&".
864 public virtual void RemoveDummyNode()
865 {
866 if ((Nodes.Count == 1 ) && (Nodes[0].Text == "@@Dummy@@"))
867 {
868 Nodes[0].Remove();
869 }
870 }
It's a cause of exception
"A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in System.Windows.Forms.dll".
|
|
|
|

|
Hi
Thanks for sharing your fix!
|
|
|
|

|
Hello,
I would like to have the directories sorted.
I used at my code the follwoing extension to Yours:
private DirectoryInfo[] SortDirArray( DirectoryInfo[] unsorted )
{
try
{
Array.Sort<DirectoryInfo>( unsorted, new
Comparison<DirectoryInfo>( delegate( DirectoryInfo d1, DirectoryInfo d2 )
{
return string.Compare( d1.Name, d2.Name );
}
)
);
}
catch
{
}
return unsorted;
}
public virtual void RequestSubDirs(TreeViewFolderBrowserHelper helper, TreeNodePath parent, TreeViewCancelEventArgs e)
{
if(parent.Path==null) return;
DirectoryInfo directory = new DirectoryInfo(parent.Path);
new System.Security.Permissions.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess.PathDiscovery, directory.FullName).Demand();
foreach( DirectoryInfo dir in SortDirArray(directory.GetDirectories()))
{
if ((dir.Attributes & System.IO.FileAttributes.System) == System.IO.FileAttributes.System)
{
continue;
}
if ((dir.Attributes & System.IO.FileAttributes.Hidden) == System.IO.FileAttributes.Hidden)
{
continue;
}
TreeNodePath newNode = this.CreateTreeNode(helper, dir.Name,dir.FullName,false,((helper.TreeView.CheckboxBehaviorMode != CheckboxBehaviorMode.None) && (parent.Checked)),false);
parent.Nodes.Add(newNode);
try
{
if(dir.GetDirectories().GetLength(0) > 0)
{
newNode.AddDummyNode();
}
}
catch{}
}
}
Perhaps You can include it into Yours.
Thank You.
|
|
|
|

|
Hi
Thanks for sharing your extension!
|
|
|
|
|

|
when I select a folder that has subfolders it will check all the subfolders but if I click on the folder again it will NOT de-select the subfolders? Any way to fix that?
modified on Wednesday, June 8, 2011 12:08 PM
|
|
|
|

|
This seems to work for me ... at line 581 in TreeViewFolderBrowser.cs I commented out ...
also, to add the names of recursed folders to the list ...
in TreeViewFolderBrowser.cs at line 601 ... change ExchangeFoldersRec(e.Node as TreeNodePath,false); to ExchangeFoldersRec(e.Node as TreeNodePath,check);
Bummer is, even after I butchered this, and some other code, it generally only added 1 subfolder deep of recursion to folderlist. The caveat is that it will only recurse as deep as the tree has been expanded because it is lazy-loaded. ie - the deeper levels of the tree that have not been expanded have not been populated with any information.
Meddling with this code makes the folderlist worthless, out of sync with the checkboxes, unless you figure out a way to automagically recurse all the way down on a folder that has been checked.
As it stands, including my meddling, you can't reliably make a folderlist with each and every folder that is checked because all of the tree branches have to be expanded.
Still, it works as promised and this is mentioned in the article.
www.CADbloke.com
The Broadcast Systems Documentation SYSTEM
"The mass of men lead lives of quiet desperation"
-Zen & the Art of Motorcycle Maintenance
modified 23 Nov '11 - 23:15.
|
|
|
|

|
Thanks for your support!
Good job!
|
|
|
|

|
Converted, successfully, to C# 2008 Express.
I think because it is Express, I don't see the TreeViewFolderBrowser in my toolbox - will have to use Save as and then delete all unnecessary code.
Now for the stupid bit!! Having selected the folders, how to I access the files in the selected folders - want to add them to a list.
Thanks
Nigel
|
|
|
|

|
I'm very very new to C#.After I have study your code,I notice that It's under Raccoom.TreeViewFolderBrowser.dll. However, I don't know how did you add it to the project since it's inside the dll again, or I'm just too new for C#.
|
|
|
|

|
I'm using this in my .NET 2.0 project, and it works great on my Vista box.
However, when I give the executable to the client who is running XP, it immediately throws an exception with this text:
Unable to cast COM object of type 'Shell32.ShellClass' to interface type 'Shell32.IShellDispatch5'. This operation failed because the QueryInterface call on the COM component <snip> failed <snip> at Raccoom.Windows.Forms.TreeViewFolderBrowser.Populate(...
Any help in solving this problem would be greatly appreciated.
|
|
|
|
|

|
Thanks, that did help.
If I build the project on XP, it works fine on both platforms. I'm using VMWare to run XP on my Windows 7 box. Thanks again!
|
|
|
|

|
Has anyone added multicolumn support to include Date and Size?
|
|
|
|

|
I'm trying to get a context menu to show up when the user right-clicks anywhere in the control. Right now, it seems the MouseClick event fires only if the mouse is over text, but even then it doesn't display the context menu. Any tips?
|
|
|
|

|
Please check out the TreeViewFolderBrowserDataProviderShell32 source code. This class shows off how to invoke a custom context menu.
BTW: The TreeView creates an internal context menu instance which it will route to the attached data provider when the user right clicks on a node. Caused by the hit test it just shows off if the user clicks over a node rectangle.
Hope this helps
|
|
|
|

|
I could really use something like
public virtual void Populate(List<string> path_list)
Maybe it is there, and I just didn't find it ...
So I put the folowing code to the form and it works well:
private void fill()
{
tvfb.Populate();
DataTable dt = Base.Select(@"SELECT * FROM CheckedFolder;"); List<string> path_list = new List<string>();
foreach (DataRow dr in dt.Rows)
path_list.Add(dr["Path"].ToString());
path_list.Sort();
checkFolders(path_list);
}
private void checkFolders(List<string> path_list)
{
foreach (TreeNodePath tn in tvfb.Nodes)
{
foreach (string s in path_list) {
if (tn.Path == Regex.Match(s, @"[A-Z]:\\(?=.)").Value)
{
tn.Expand();
break;
}
}
if (path_list.Contains(tn.Path))
tn.Checked = true;
checkTreeNode(tn, path_list);
}
}
private void checkTreeNode(TreeNodePath tnParent, List<string> path_list)
{
foreach (TreeNodePath tn in tnParent.Nodes)
{
string regex = @"[A-Z]:";
regex += regexAddSubDir(tn); regex += @"(?=\\)";
foreach (string s in path_list) {
if (tn.Path == Regex.Match(s, regex).Value)
{
tn.Expand();
break;
}
}
if (path_list.Contains(tn.Path))
tn.Checked = true;
checkTreeNode(tn, path_list);
}
}
private string regexAddSubDir(TreeNodePath tn)
{
string ret = "";
if (tn.Parent != null) {
ret += @"\\([^\\]+)";
ret += regexAddSubDir((TreeNodePath)tn.Parent);
}
return ret;
}
It could also be implemented in the TreeViewFolderBrowser class, I guess.
|
|
|
|

|
Thanks for sharing...
By design this role is played by the SelectedDirectories list which is provided by the tree view
myTreeView.SelectedDirectories
this list serves as the data source for all the selection stuff like in your scenario.
Did you try this as mentionded above in first place?
|
|
|
|

|
So that is how it woks ...
tvfb.Populate();
StringCollection sc = new StringCollection();
sc.Add("C:\\Program Files");
tvfb.SelectedDirectories = sc;
the only difference is that it does not expand the parent nodes of checked nodes. Or is that also somewhere I did not look?
P.S.
Great work!
modified on Friday, April 3, 2009 5:13 AM
|
|
|
|

|
seems that you rather spend your time incorporating the code instead of reading the article
just kidding... AFAIR there is a ShowFolder(string path) method.
I think it's not a common scenario that you expand all "selected" folders.. imagine one has 1000 selections... the time the user is waiting until everything is in place is simply too long...
that's the reason why the folders which have selected child folders and files have a bold font.. so the user can navigate as he likes to "some" selected folders...
but that's maybe just a "concept" and not a scenario every app can use...
maybe you just need to call ShowFolder for each selected directory in tvfb.SelectedDirectories
PS: Thanks.. you're welcome
|
|
|
|

|
I suspected it would be something simple.
So it was all there all the time.
...
I tried it, and ...
ShowFolder also has that bug mentioned in the other tread.
- If I set the SelectedDirectories first and then show the folders all subfolders of checked folder get the checked mark, because GetSubDirs is not called.
- If I show the folders first, then none of them gets the checked mark.
Maybe I should just add the GetSubDirs somewhere. I'll look into it.
My code works fine, because it expands the node before it is checked.
And I altered the OnBeforeCheck as described in the other tread, so it would work fine even if the nodes don't get expanded.
modified on Friday, April 3, 2009 5:46 AM
|
|
|
|

|
After some more testing I just added the following to the TreeViewFolderBrowser.cs. Works for me.
It does take longer to load than just setting the SelectedDirectories, but the checkmark bug just bugs me too much.
Thanks again for your great work!
public virtual void Populate(StringCollection path_list, bool expandNodes)
{
Populate();
foreach (TreeNodePath tn in this.Nodes)
{
foreach (string s in path_list) {
if (tn.Path == Regex.Match(s, @"[A-Z]:\\(?=.)").Value)
{
if (expandNodes)
tn.Expand();
else
{
try { GetSubDirs(tn, new TreeViewCancelEventArgs(null, false, TreeViewAction.ByMouse)); }
catch { }
}
break;
}
}
if (path_list.Contains(tn.Path))
tn.Checked = true;
checkTreeNode(tn, path_list, expandNodes);
}
}
private void checkTreeNode(TreeNodePath tnParent, StringCollection path_list, bool expandNodes)
{
foreach (TreeNodePath tn in tnParent.Nodes)
{
string regex = @"[A-Z]:";
regex += regexAddSubDir(tn); regex += @"(?=\\)"; foreach (string s in path_list) {
if (tn.Path == Regex.Match(s, regex).Value)
{
if (expandNodes)
tn.Expand();
else
{
try { GetSubDirs(tn, new TreeViewCancelEventArgs(null, false, TreeViewAction.ByMouse)); }
catch { }
}
break;
}
}
if (path_list.Contains(tn.Path))
tn.Checked = true;
checkTreeNode(tn, path_list, expandNodes);
}
}
private string regexAddSubDir(TreeNodePath tn)
{
string ret = ""; if (tn.Parent != null) { ret += @"\\([^\\]+)"; ret += regexAddSubDir((TreeNodePath)tn.Parent); }
return ret;
}
|
|
|
|

|
ok, I guess I'll have to crawl through all the contributed code to update my code base and release a bug fixed (and btw. tested on Windows 7 beta) version ,)
looks like I'll have some coding nights ahead
PS: Are you willing to get your hands on a pre released version?
|
|
|
|

|
Thank you, I will be glad to do some beta testing.
As for OS, I'm just sticking with XP for now. So no help for Vista or W7 from me.
|
|
|
|

|
that's fine.. so the major OS Versions (XP, Vista and Windows 7) are concerned
|
|
|
|

|
You need to scan for subfolder before you check ... put:
TreeNodePath node = e.Node as TreeNodePath;
try
{
GetSubDirs(node, e);
}
catch {}
in OnBeforeCheck, just like in OnBeforeExpand. (Catch can stay empty, try is good enough.)
It might also help with recursive check, I didn't look into that, since I only need a sigle check.
|
|
|
|

|
Hello,
at first, thanks for te great article and control. However, i encoutered some problems running the demo on Vista. The "Failed to get icon index" assertion is shown when the control is populating. The issue is caused by the fact that your code attempts to get icon for system folders like Control panel and the fileName variable in:
SHGetFileInfo(fileName, dwAttr, ref shfi, shfiSize,((uint)(dwFlags) | (uint)iconState));
equals a string like "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
Have you any thoughts on how to avoid the problem?
I think the problem could be solved by using PIDL instead of fileName, but i have no idea how to get PIDL for the FolderItem.
|
|
|
|

|
Hi,
You're welcome. I guess the code base needs a refresh that boost it from the year 2003 to 2009 where Windows 7 comes in ,)
If someone already fixed that part of the code please contribute.
Maybe you just need to look for a similiar articles here at cp and merge the SystemImageList part... at least that would be my happy guess to do it.
|
|
|
|

|
I think this is caused by the fact that ZIP archives are also marked as a folder.
just add a clause to ignore those (and maybe .rar also, didn't check that) and you're good to go.
(worked for me in any case)
|
|
|
|

|
I have a question what will be your strategy to load folder containing 1 million files in it. I have seen many File Explorer controls but the all use shell and hang while loading such folder or drive.
|
|
|
|

|
Hi imadulhaq,
Show me a user that wants/needs to work with a million files at one moment in time ,) If one can't create/show so much files in one folder (OS Shell) why does one want to see them at one in a custom application? Where's the use case for your question?
|
|
|
|

|
Well you are right.
I am working on a Backup application. The application facilitates user to take backup of folders/ directories of his choice. Therefore, we'll have to support files/folders in millions present in a folder/ directory as well. You are absolutely right about Shell, it hangs and very slow while enumerating large number of files.
What is your advice to handle such a situation?
|
|
|
|

|
First I would investigate how good backup softwares today solved this kind of problem. Second I think no matter what kind of software you're writing the user will never need and wants to see thousands of files on the screen.
Strategies might be to create virtual groups for the files by
- file extension
- by alphabet starting letter
- by Creation Date/Week/Year or a like
into a virtual folder and let the user expand just that folder providing just a minimal and also workable subset of the total files.
Maybe you better of providing a vista like instant search where the user can search/query for the files he needs to see?
|
|
|
|

|
Hi
Removable hard disks ( USB hard disk ) are being displayed even when selected drive type is Local Disk. This problem doesn't occur with removable flash drives. Have you also faced the same issue with this application?
In my application code also if I query win32_logicaldisk objects, win32_logicaldisk object coresponding to removable hardisk gives drive type = 3 ( that is for local disks ) while it should give 2. For removable flash drives the drivetype value is 2 as expected. I think that is the reason for the problem.
Can you please let me know if you find any solution for that?
|
|
|
|

|
Hi,
I'm not aware of this issue. Maybe it's just the usb hard disk driver in use that specifies the drive type?
I have no idea, sorry
|
|
|
|
|

|
currently I'm trying to repro this stuff on a Windows Server 2008, no luck
did you work with your mouse oder the keyboard? Did you expand each level of his own or by '*' key to expand all children?
|
|
|
|
|

|
You're welcome to contribute your changes and I will incorporate those into the latest code base for updating the article, interested?
You will be named of course
|
|
|
|

|
Off course, always glad to help.
What is the best way to send you the code? E-Mail?
I updated the project to VS 2008 also (since I don't have any other version )
Grtz!
|
|
|
|

|
Is there a trick to get mapped network drives to show up? I have DriveTypes set to All and I don't see my mapped network drivers. Could this be a Vista OS problem?
|
|
|
|

|
Hi,
Maybe, do you use the Shell32 Provider? Do you see the network drives in the windows explorer?
|
|
|
|

|
Are the drives connected?
|
|
|
|

|
Is possible set icons folders, files, (drivers etc...) on transparent color or other color than white. Because when I set bacground color of TreeViewFolderBrowser control on black then icons have still white color. Thank for any idea.
|
|
|
|

|
Hi,
Never tried but does it "only" happen when you change the backcolor after the control is visible already or does it happen all the time?
Maybe you have to re-initialize the ShellImageList again after the back color has changed, not sure how to handle the shell image list in terms of back color.
|
|
|
|

|
Hi,
Never tried but does it "only" happen when you change the backcolor after the control is visible already or does it happen all the time?
It does not matter. I try both ways.
Maybe you have to re-initialize the ShellImageList again after the back color has changed, not sure how to handle the shell image list in terms of back color.
Could you show me some example how do it?
|
|
|
|

|
With "not sure how to handle" I meant I have no clue about it, sorry
|
|
|
|

|
Chris,
Great code. One question if I may: I would like the treeview to display normal files also. Is there a way get this functionality?
Thanks in advance.
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Supports Explorer, SingleChecked and RecursiveChecked mode (checkboxes). Lets you specify the displayed drive types etc...
| Type | Article |
| Licence | LGPL3 |
| First Posted | 1 Jul 2003 |
| Views | 341,994 |
| Bookmarked | 234 times |
|
|