Set a treeview to specific location - vb.net

I have a folder in my C: drive that I want to access as soon as my form loads. I don't want to scroll through opening each node everytime. I'm wanting to use a treeview as I know how to use a lot of the features in these and it will suit my purpose.
I shall give you an example of what i am wanting using a basic file structure:
C:\Users\user\Documents\Visual Studio 2010\Projects
This would take me a number of nodes to gain access to if I was to to it through the entire treeview. I want my treeview to to start with, so the main node to be
Projects
How would I go about doing this?

Here is an example which assumes the name of the node is the full path of the folder:
Protected Overrides Sub OnLoad(e As EventArgs)
Dim name As String = "c:\users\blairg\documents\visual studio 2010\projects"
Dim testNode As New TreeNode("Projects")
testNode.Name = name
TreeView1.Nodes.Add(testNode)
Dim node() As TreeNode = TreeView1.Nodes.Find(name, True)
If node.Count = 1 Then
TreeView1.SelectedNode = node(0)
End If
MyBase.OnLoad(e)
End Sub

I am sure that the answer above would work. However i managed to sort it out by doing:
Dim backupfolder As String = netpath & "\MANUFPC BACKUP PROCESS\" & site & "\" & factory & "\" & line & "\" & pc
Dim mRootNode As New TreeNode
mRootNode.Text = pc
mRootNode.Tag = backupfolder
mRootNode.Nodes.Add("*DUMMY*")
'adds plus icon to allow extension
backupFolderDirectory.Nodes.Add(mRootNode)
then the two other functions:
Private Sub TreeView1_BeforeCollapse(ByVal sender As Object, ByVal e As TreeViewCancelEventArgs) Handles backupFolderDirectory.BeforeCollapse
' clear the node that is being collapsed
e.Node.Nodes.Clear()
' add a dummy TreeNode to the node being collapsed so it is expandable
e.Node.Nodes.Add("*DUMMY*")
End Sub
Private Sub TreeView1_BeforeExpand(ByVal sender As Object, ByVal e As TreeViewCancelEventArgs) Handles backupFolderDirectory.BeforeExpand
' clear the expanding node so we can re-populate it, or else we end up with duplicate nodes
e.Node.Nodes.Clear()
' get the directory representing this node
Dim mNodeDirectory As DirectoryInfo
mNodeDirectory = New DirectoryInfo(e.Node.Tag.ToString)
' add each subdirectory from the file system to the expanding node as a child node
Try
For Each mDirectory As DirectoryInfo In mNodeDirectory.GetDirectories
' declare a child TreeNode for the next subdirectory
Dim mDirectoryNode As New TreeNode
Dim mystring(1) As String
mystring(0) = mDirectory.FullName
mystring(1) = "directory"
' store the full path to this directory in the child TreeNode's Tag property
mDirectoryNode.Tag = mystring(0)
' set the child TreeNodes's display text
mDirectoryNode.Text = mDirectory.Name
' add a dummy TreeNode to this child TreeNode to make it expandable
mDirectoryNode.Nodes.Add("*DUMMY*")
' add this child TreeNode to the expanding TreeNode
e.Node.Nodes.Add(mDirectoryNode)
Next
For Each mFiles As FileInfo In mNodeDirectory.GetFiles
' declare a child TreeNode for the next subdirectory
Dim mFileNode As New TreeNode
Dim mystring(1) As String
mystring(0) = mFiles.FullName
mystring(1) = "file"
' store the full path to this directory in the child TreeNode's Tag property
mFileNode.Tag = mystring(0)
' set the child TreeNodes's display text
mFileNode.Text = mFiles.Name
' add this child TreeNode to the expanding TreeNode
e.Node.Nodes.Add(mFileNode)
Next
Catch ex As IOException
'sets up 2 different exceptions then the last one catches other exceptions that could be made from adding folder/files etc
e.Node.Remove()
MsgBox("Device/Folder not accessible", MsgBoxStyle.OkOnly, "Device not Ready")
Catch exc As NullReferenceException
e.Node.Remove()
MsgBox("Sorry this File/Folder can not be added", MsgBoxStyle.OkOnly, "Sorry")
Catch exce As Exception
e.Node.Remove()
MsgBox("Device/Folder not accessible", MsgBoxStyle.OkOnly, "Device not Ready")
End Try
End Sub

Related

How to check if sub-folder text file exists

I am trying to search if a text file in a sub-folder exists.
This is the code I am using:
'Checks the program's root folder to see if the root folder exists.
Dim FolderName = New DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Cake Orders\" & TextBox1.Text))
Dim McKnwoll As String = Path.Combine(FolderName.FullName, Trim(TextBox2.Text) & (" ") & Trim(TextBox3.Text) + ".RTO")
If Not McKnwoll.Exists Then
‘Message to user that file does not exist in sub-folder
Else
‘Message to user that file does exists in sub-folder
End If
I am getting an error that 'Exists' is not a member of 'String'. How can I re-work my code to check if the text file whose name is in the format of "TextBox2.Text & (" ") & TextBox3.Text + ".RTO"; exists.
I am using Visual Basic 2010 Express. Thank you.
File.Exists returns a Boolean indicating whether a file at a certain path exists:
If File.Exists(pathToFile) Then
...
End If
Be sure to include Imports System.IO at the top of your source code file.
You seem quite new in programming. Welcome.
That error message you got ('Exists' is not a member of 'String') tells you exactely what is wrong: You try to ask a string (some text) whether it exists, but what you like to do is to ask a file whether it exists.
The class that provides information about a file is called "FileInfo", and FileInfo has an "Exists" property that you can call:
Dim myFileInfo As New FileInfo(McKnwoll)
If myFileInfo.Exists Then
'do something
End If
That's the object oriented answer, Heinzi's more service oriented one but works, of course, too.
There have been several other small issues I noticed with your code, e.g.
"Cake Orders\" & TextBox1.Text
does not use Path.Combine but makes a string concatenation using fix a "\" as directory separater. Or that the DirectoryInfo is not really used here, the string to the folder is enough.
You also try to handle 3 different issues (reading the values from the user interface, constructing the fullname of the file, checking whether the file exists) in one single code block. I would split them into 3 different ones (actually 4, I would add another one for displaying error messages).
Your simple few lines of codes could be complicated like this ;-)
Imports System.IO
Imports System.Text
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ReadFileIfPossible(TextBox1.Text, TextBox2.Text, TextBox3.Text)
End Sub
Private Sub ReadFileIfPossible(subfolder As String, part1 As String, part2 As String)
'Get the path to the RTO file
Dim myFilePath As String = Nothing
Try
myFilePath = GetRtoFilePath(subfolder, part1, part2)
Catch ex As Exception
DisplayErrorMessage("Error constructing file name! Please check the values of TextBox1, TextBox2 and TextBox3.")
Return
End Try
'Get the file info
Dim myFile As FileInfo = Nothing
Try
myFile = New FileInfo(myFilePath)
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Check whether it exists
Dim myExists As Boolean = False
Try
myExists = myFile.Exists 'it's IO, everything might throw an exception...
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Display message if not found
If (Not myExists) Then
DisplayErrorMessage("File ""{0}"" could not be found!", myFilePath)
Return
End If
'Read the file
Dim myLines As String() = Nothing
Try
myLines = File.ReadAllLines(myFile.FullName, New UTF8Encoding(True))
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Do something with it...
End Sub
Private Shared Function GetRtoFilePath(subfolder As String, part1 As String, part2 As String) As String
'Check args
If (subfolder Is Nothing) Then Throw New ArgumentNullException("subfolder")
If (part1 Is Nothing) Then Throw New ArgumentNullException("part1")
If (part2 Is Nothing) Then Throw New ArgumentNullException("part2")
'Normalize args
part1 = part1.Trim()
part2 = part2.Trim()
'Build path
Dim myDesktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim myFolderPath As String = Path.Combine(myDesktopPath, "Cake Orders")
myFolderPath = Path.Combine(myFolderPath, subfolder)
Dim myFileName As String = String.Format("{0} {1}.RTO", part1, part2)
Dim myResult As String = Path.Combine(myFolderPath, myFileName)
myResult = Path.GetFullPath(myResult)
'Return result
Return myResult
End Function
Private Sub DisplayErrorMessage(message As String, ParamArray args As Object())
Dim myMsg As String = String.Format(message, CType(args, Object()))
MsgBox(myMsg, MsgBoxStyle.OkOnly, "Error")
End Sub
End Class
Have fun.

How to search multiple treeview nodes at a particular depth

Please does anyone know how I can search the text of multiple treeview nodes at a particular depth on the click of a button? The treeview nodes are arranged as follows:
I want to prevent the user from entering duplicate grandchild nodes of the same title into the treeview, i.e entering 'Movie 2' a second time should throw up a message that Movie 2 has already been entered; if not, then add the new movie title.
The grandchild node titles are fed into the treeview from a textbox. I am using Visual Basic 2010 Express. Thank you in advance.
The code I am using is:
Private Sub Button11_Click(sender As System.Object, e As System.EventArgs) Handles Button11.Click
'New movie title has been introduced into the study
Dim SelectedNode As TreeNode
SelectedNode = TreeView1.SelectedNode
'To avoid entering duplicate movies title
Dim NewMovieName As String = TextBox1.Text.Trim.ToLower ' The content of that node
Dim parentNode = SelectedNode.Parent ' Get the parent
Dim childNodes As TreeNodeCollection = parentNode.Nodes ' Get all the children
Dim WeHaveDuplicate As Boolean = False ' We use this to flag if a duplicate is found. Initially set to false.
For Each tempNode As TreeNode In childNodes
'Test that we have the same name but not referring to the same node
If tempNode.Text.Trim.ToLower = NewMovieName And tempNode IsNot parentNode Then WeHaveDuplicate = True
Next
If WeHaveDuplicate = True Then
'Send message to user
MsgBox(TextBox1.Text & " as a parameter has already been considered.", vbOKOnly)
Exit Sub
Else
parentNode.Nodes.Add(TextBox1.Text)
TreeView1.ExpandAll()
End If
Exit Sub
End Sub
All help would be greatly appreciated. Thank you.
Here is a little snippet that I use frequently. It will find a node by it's text. It will also highlight and expand the node found.
Notice it is recursive, so it will search to the bottom of the supplied node collection (param). If this supplied collection is the root node, then it will search the whole tree.
I usually apply a unique string to the node.tag property. If you adjust the function to look for that, you can have duplicate text displaying while still having a unique string to look for...
''' <summary>
''' Find and Expand Node in Tree View
''' </summary>
Private Function FindNode(ByVal SearchText As String, ByVal NodesToSearch As TreeNodeCollection, ByVal TreeToSearch As TreeView) As TreeNode
Dim ReturnNode As TreeNode = Nothing
Try
For Each Node As TreeNode In NodesToSearch
If String.Compare(Node.Text, SearchText, True) = 0 Then
TreeToSearch.SelectedNode = Node
Node.Expand()
ReturnNode = Node
Exit For
End If
If ReturnNode Is Nothing Then ReturnNode = FindNode(SearchText, Node.Nodes, TreeToSearch)
Next
Catch ex As Exception
Throw
End Try
Return ReturnNode
End Function
Edited:
Per your recent comment,
You might try using it like this...
WeHaveDuplicate = (FindNode("Movie 2", TreeView1.Nodes, TreeView1) Is Nothing)
If WeHaveDuplicate = True Then
'message user of dupe
Else
'add movie
End If

How to remove files from a directory if they don't contain the list of specified files provided?

I'm currently doing a project where I need to search through a specific directory for files. If the files found are not the approved extension then the files must be moved to an archive folder. I need to user to be allowed to remove and add extensions so the list is not a set size and will most likely change weekly.
So far I'm able to loop through the directories and list all the files in there into a listbox. My problem comes when trying to differentiate between the approved list and the current list and I can't narrow down the files and display them in the list box.
My error is : 'An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll' where my 'list1' variable count is 0 because no children were found even when there are matching approved data and current data.
Any help would be appreciate from stack overflow community! Thanks!!
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim list1 As List(Of String)
list1 = (From item As String In Me.ListBox1.Items Select item Where Me.ListBox1.Items.Contains(Me.lstApprovedItems.Items)).ToList()
ListBox1.Items.Add(list1(0))
End Sub
Dim fri As FileInfo
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim FileName1 As String = ""
Dim dir2 As New DirectoryInfo("D:\Administrator\Desktop\File Management System v0.2\File Management System\File Directories\File Directories\00000000.00F")
Dim dir1 As DirectoryInfo() = dir2.GetDirectories()
Dim fri2 As DirectoryInfo
For Each fri2 In dir1
FileName1 = Convert.ToString(fri2.Name)
Dim dir As New DirectoryInfo("D:\Administrator\Desktop\File Management System v0.2\File Management System\File Directories\File Directories\00000000.00F\" + FileName1)
Dim fiArr As FileInfo() = dir.GetFiles()
For Each Me.fri In fiArr
ListBox1.Items.Add(fri.Name)
Next fri
Next
End Sub
End Class
There are several ways to go about this, this way is similar to what you have.
' first get OK extension into an array (or list)
Dim Auth(lbAuthExt.Items.Count - 1) As String
lbAuthExt.Items.CopyTo(Auth, 0)
' storage for the result
' only save the Authorized ones if that is all you care about
Dim AuthList As New List(Of FileInfo)
Dim NoAuthList As New List(Of FileInfo)
Dim dir = New DirectoryInfo("C:\Temp")
For Each fi As FileInfo In dir.GetFiles
If Auth.Contains(fi.Extension) Then
AuthList.Add(fi)
Else
NoAuthList.Add(fi)
End If
Next
I am saving FileInfo because (presumably) you might display the names to the user without all the redundant path info. But your code will need the full path name for later Copy/Move ops.
' set the list as the datasource
lbResult.DataSource = AuthList
' display file name
lbResult.DisplayMember = "Name"
' return full name to code
lbResult.ValueMember = "FullName"
The code can of course simply loop on AuthList to do its job. If you need to show the results to the user first, there is no need to make 2 copies. DisplayMember is used to tell the ListBox which property value to display while retaining all the other info in the list.
Finally, a linq version which simply saves the full file name:
Dim myAuthList = (From func In Directory.EnumerateFiles("C:\Temp", "*.*",
System.IO.SearchOption.AllDirectories)
Where Auth.Contains(Path.GetExtension(func),
StringComparer.InvariantCultureIgnoreCase)).ToList

VB.NET + Add folders to treeview and files to listview

I want to create a simple printer manager to use in our Terminal server environment. Because of GPO restrictions, there are limits of what built-in functionality I can use. So I decided to try to write my own simple GUI to do that.
Now, the printers are distributed in a folder, with subfolders to categorize them. In each folder there are .lnk files to the actual printer on the printserver.
What I want to do is to populate a treeview with the folders, and the printers in a listview, based on which item is clicked on the treeview.
I've already managed to search for directories and to search the files for each item I've clicked. But I realized, why not use a collection or similar to do this during the startup of the form? That way, it'll be faster. Because right now, there's a small delay each time I click an item in the treeview. Because it scans for files each time.
How can I add the same to a collection and use that instead?
Here's my current code:
Public Sub populateTreeView(ByVal strPath As String)
Dim di As New IO.DirectoryInfo(strPath)
Dim diar1 As IO.DirectoryInfo() = di.GetDirectories()
Dim dra As IO.DirectoryInfo
For Each dra In diar1
ImageList1.Images.Add(GetSmallIcon(dra.FullName))
TreeView1.Nodes.Add("", dra.Name, nIndex)
nIndex = nIndex + 1
Next
End Sub
Private Sub TreeView1_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterSelect
ListView1.Clear()
nIndex = 0
Dim di As New IO.DirectoryInfo(strIniSettings & "\" & TreeView1.SelectedNode.Text)
Dim diar1 As IO.FileInfo() = di.GetFiles()
Dim dra As IO.FileInfo
For Each dra In diar1
Dim strName As String
strName = Replace(dra.Name, ".lnk", "")
ImageList2.Images.Add(GetLargeIcon(dra.FullName))
ListView1.Items.Add("", strName, nIndex)
nIndex = nIndex + 1
Next
End Sub
Notice the Imagelists? I also get the Icon for each item as well.
Since your data is not complex, a simple LookUp may be the right collection for you (or just a plain Dictionary).
Just query the printers once, and store it in a member variable, or just use the Tag property of the TreeNodes so store the file names.
In the example below, I'm using a simple Linq query to create a LookUp where the Key is the directory name (you could also just use full path to the directory), and the items are the file names.
You could then either query the collection by a given Key (the directory name), or use the Tag property.
LINQPad example:
Sub Main
' query printers once (just replace C:\test with your path)
' store the result in a member variable of your form
Dim printer = new DirectoryInfo("C:\test").GetDirectories() _
.SelectMany(Function(d) d.GetFiles()) _
.ToLookup(Function(f) f.Directory.Name, Function(f) f.Name)
' Or, using a Dictionary
' Dim printer = new DirectoryInfo("C:\test").GetDirectories() _
' .ToDictionary(Function(d) d.Name, Function(d) d.GetFiles().Select(Function(f) f.Name).ToList())
Dim l = new ListView() With {.Dock = DockStyle.Right}
Dim t = new TreeView() With {.Dock = DockStyle.Left}
AddHandler t.AfterSelect, Sub(s, e)
' This is your AfterSelect event handler
' The filenames are stored in the Tag of the TreeNode
' You could also use 'For Each p As String in printer(e.Node.Text)'
l.Items.Clear()
For Each p As String in e.Node.Tag
Dim item = l.Items.Add(p.Replace(".lnk", ""))
'TODO: Set Icon on item
Next
End Sub
' Populate TreeView once
For Each folder in printer
Dim fNode = t.Nodes.Add(folder.Key)
'TODO: Set Icon on fNode
' store the files in the Tag of the node.
' You don't have to, but it will make it easier
fNode.Tag = folder
Next
' Show test form
Dim w = new Form()
w.Controls.Add(t)
w.Controls.Add(l)
w.Show()
End Sub

File Icons and List view

How to retrieve file icons associated with the file types and add them with the items of Listview in vb.net
I read about SHGetFileInfo but I didn't understand anything from that
please give me solution or please explain me ho system works with the .net controls in details
Having looked up SHGetFileInfo I can see why you're confused by it, but I think it might be slightly overkill for what I think you're trying to do i.e. enumerating the contents of a folder and adding items to the Listview.
If we have a form that contains a ListView and an ImageList, with the two related by having the ListView's LargeImageList property set to the ImageList, then here's how we put the contents of a folder into the ListView with the icons coming from the associated EXE file for each file.
Imports System.IO
Imports System.Drawing
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim dirInfo As DirectoryInfo
Dim fileInfo As FileInfo
Dim exePath As String
Dim exeIcon As Icon
dirInfo = New DirectoryInfo(path_to_some_folder
'We use this For...Each to iterate over the collection of files in the folder
For Each fileInfo In dirInfo.GetFiles
'We can only find associated exes by extension, so don't show any files that have no extension
If fileInfo.Extension = String.Empty Then
Else
'Use the function to get the path to the executable for the file
exePath = GetAssociatedProgram(fileInfo.Extension)
'Use ExtractAssociatedIcon to get an icon from the path
exeIcon = Drawing.Icon.ExtractAssociatedIcon(exePath)
'Add the icon if we haven't got it already, with the executable path as the key
If ImageList1.Images.ContainsKey(exePath) Then
Else
ImageList1.Images.Add(exePath, exeIcon)
End If
'Add the file to the ListView, with the executable path as the key to the ImageList's image
ListView1.Items.Add(fileInfo.Name, exePath)
End If
Next
End Sub
GetAssociatedProgram comes from developer.com
Public Function GetAssociatedProgram(ByVal FileExtension As _
String) As String
' Returns the application associated with the specified
' FileExtension
' ie, path\denenv.exe for "VB" files
Dim objExtReg As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot
Dim objAppReg As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot
Dim strExtValue As String
Try
' Add trailing period if doesn't exist
If FileExtension.Substring(0, 1) <> "." Then _
FileExtension = "." & FileExtension
' Open registry areas containing launching app details
objExtReg = objExtReg.OpenSubKey(FileExtension.Trim)
strExtValue = objExtReg.GetValue("").ToString
objAppReg = objAppReg.OpenSubKey(strExtValue & _
"\shell\open\command")
' Parse out, tidy up and return result
Dim SplitArray() As String
SplitArray = Split(objAppReg.GetValue(Nothing).ToString, """")
If SplitArray(0).Trim.Length > 0 Then
Return SplitArray(0).Replace("%1", "")
Else
Return SplitArray(1).Replace("%1", "")
End If
Catch
Return ""
End Try
End Function
At the end of all of that, when you run this code on this folder:
alt text http://www.philippursglove.com/stackoverflow/listview1.png
you should get:
alt text http://www.philippursglove.com/stackoverflow/listview2.png
If you know the file name of the file whose icon you want, you can use the System.Drawing.Icon.ExtractAssociatedIcon function for that purpose. e.g.
Icon ico = System.Drawing.Icon.ExtractAssociatedIcon(#"C:\WINDOWS\system32\notepad.exe");
You can also refer to my answer to a related question for more implementation details.