I Made an application to download a folder from a given sharepoint site, but its consuming memory above 600,000K once i click on Connect button, anyone can give suggestion to improve my code ?
I Tried to debug my form and problem is coming at method " private void MapWebs(SPWebCollection webList, TreeNode webparentNode)" where its calling itself again and again to go through each single web and its sub web, however I checked in the start when i click on connect and it goes through code line
using (SPSite CurrentSite = new SPSite(tbSite.Text))
The memory usage goes from 20,000 K to 40,000 K (approx)
In order to run this application you must have sharepoint installed on yur PC, an example of this type of app is on this link ,
enter link description here
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using System.IO;
namespace WindowsFormsApplication3
{
public partial class MainWindow : Form
{
public MainWindow()
{
InitializeComponent();
}
//Connects to Sharepoint site provided and populates Webs and Subwebs and subwebs....
private void bConnect_Click(object sender, EventArgs e)
{
//Getting current site
using (SPSite CurrentSite = new SPSite(tbSite.Text))
{
//Opening TopLevel Web for Site given
using (SPWeb TopLevelWeb = CurrentSite.OpenWeb())
{
//Clearing all the nodes in TreeWeb
TreeWeb.Nodes.Clear();
//Creating a root (First Node for webtree) which will be Top Level web's title
TreeNode rootWebNode = new TreeNode(TopLevelWeb.Title);
//Giving node a tag, which will be used later on in order to get value of node
rootWebNode.Tag = TopLevelWeb;
//Check if Top Level Web got any Sub webs if it does, it will create a new node for them
//Calls Map Webs to check for more sub webs + mapping them on webtree as nodes
foreach (SPWeb CurrentWeb in TopLevelWeb.Webs)
{
try
{
TreeNode webNode = new TreeNode(CurrentWeb.Title);
webNode.Tag = CurrentWeb;
MapWebs(CurrentWeb.Webs, webNode);
TreeWeb.Nodes.Add(webNode);
}
finally
{
if (CurrentWeb != null)
CurrentWeb.Dispose();
}
}
}
}
}
// Maps Webs and there sub webs on webtree
private void MapWebs(SPWebCollection webList, TreeNode webparentNode)
{
for (var i = 0; i < webList.Count; i++)
{
TreeNode node = new TreeNode(webList[i].Name);
using (SPWeb web = webList[i])
{
node.Tag = webList[i];
webparentNode.Nodes.Add(node);
if (webList[i].Webs.Count > 0)
MapWebs(webList[i].Webs, node);
}
}
GC.Collect();
}
//when the form loads it clears the list and create new cloumns to be used
private void MainWindow_Load(object sender, EventArgs e)
{
bFolder.Enabled = false;
bConnect.Enabled = false;
lvFiles.GridLines = true;
lvFiles.View = View.Details;
lvFiles.Columns.Add("Name", lvFiles.Width/4, HorizontalAlignment.Left);
lvFiles.Columns.Add("Date Created", lvFiles.Width/3, HorizontalAlignment.Left);
lvFiles.Columns.Add("Size", lvFiles.Width / 5, HorizontalAlignment.Left);
lvFiles.Columns.Add("Time Last Modified", lvFiles.Width / 5, HorizontalAlignment.Left);
if (lvFiles.View == View.Details && lvFiles.Columns.Count > 0)
this.Width = lvFiles.Columns.Count * (lvFiles.Width / 2);
lvFiles.Columns[lvFiles.Columns.Count - 1].Width = -2;
}
//creates directory for downloading folder
private bool CreateDirectoryStructure(string baseFolder, string filepath)
{
if (!Directory.Exists(baseFolder)) return false;
var paths = filepath.Split('/');
for (var i = 0; i < paths.Length - 1; i++)
{
baseFolder = System.IO.Path.Combine(baseFolder, paths[i]);
Directory.CreateDirectory(baseFolder);
}
return true;
}
//opens an dialog box for selecting path where selected folder will be downloaded
private void bBrowse_Click(object sender, EventArgs e)
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
this.tbDirectory.Text = folderBrowserDialog1.SelectedPath;
}
}
//when a node is selected in webtree it checks for folders in it , + sub folders + folders......
private void TreeWeb_AfterSelect(object sender, TreeViewEventArgs e)
{
TreeFolder.Nodes.Clear();
TreeNode currentNode = TreeWeb.SelectedNode;
using (SPWeb oWeb = (SPWeb)currentNode.Tag)
{
foreach (SPList list in oWeb.Lists)
{
if (list is SPDocumentLibrary && !list.Hidden)
{
TreeNode folderNode = new TreeNode(list.Title);
folderNode.Text = string.Format("{0} ({1})", list.Title, list.ItemCount);
folderNode.Tag = list.RootFolder;
foreach (SPListItem listItem in list.Folders)
{
if (listItem.Folder != null)
{
TreeNode node = new TreeNode(listItem.Folder.Name);
node.Tag = listItem.Folder;
node.Text = string.Format("{0} ({1})", listItem.Folder.Name,
GetFilesCount(listItem.Folder));
MapFolders(listItem.Folder.SubFolders, node);
folderNode.Nodes.Add(node);
}
}
TreeFolder.Nodes.Add(folderNode);
}
}
}
}
//Maps folder on foldertree
private void MapFolders(SPFolderCollection folderList, TreeNode parentNode)
{
for (var i = 0; i < folderList.Count; i++)
{
TreeNode node = new TreeNode(folderList[i].Name);
node.Text = string.Format("{0} ({1})", folderList[i].Name,
GetFilesCount(folderList[i]));
node.Tag = folderList[i];
parentNode.Nodes.Add(node);
if (folderList[i].SubFolders.Count > 0)
MapFolders(folderList[i].SubFolders, node);
}
}
//Maps files in a folder to listview
private void TreeFolder_AfterSelect(object sender, TreeViewEventArgs e)
{
lvFiles.Items.Clear();
TreeNode currentNode = TreeFolder.SelectedNode;
//if (currentNode != rotnode)
//{
double TotalSize = 0;
SPFolder oFolder = (SPFolder)currentNode.Tag;
foreach (SPFile oFile in oFolder.Files)
{
TotalSize += (oFile.Length)/1024/1024;
ListViewItem LTI = new ListViewItem(oFile.Name.ToString());
LTI.SubItems.Add(oFile.TimeCreated.ToString());
LTI.SubItems.Add(oFile.Length.ToString());
LTI.SubItems.Add(oFile.TimeLastModified.ToString());
lvFiles.Items.Add(LTI);
}
label4.Text = TotalSize.ToString();
//}
}
//download selected folder + validation
private void bFolder_Click(object sender, EventArgs e)
{
TreeNode currentNode = TreeFolder.SelectedNode;
SPFolder oFolder = (SPFolder)currentNode.Tag;
foreach (SPFile file in oFolder.Files)
{
if (CreateDirectoryStructure(tbDirectory.Text, file.Url))
{
var filepath = System.IO.Path.Combine(tbDirectory.Text, file.Url);
byte[] binFile = file.OpenBinary();
System.IO.FileStream fstream = System.IO.File.Create(filepath);
fstream.Write(binFile, 0, binFile.Length);
fstream.Close();
}
}
}
//calculates files in selected folder
private int GetFilesCount(SPFolder folder)
{
int fileCount = folder.Files.Count;
foreach (SPFolder subfolder in folder.SubFolders)
{
fileCount += GetFilesCount(subfolder);
}
return fileCount;
}
//validation
private void tbSite_TextChanged(object sender, EventArgs e)
{
if (tbSite.Text != "")
bConnect.Enabled = true;
else
bConnect.Enabled = false;
}
//validation
private void tbDirectory_TextChanged(object sender, EventArgs e)
{
if (tbDirectory.Text != "" && TreeFolder.Nodes.Count != 0)
bFolder.Enabled = true;
else
bFolder.Enabled = false;
}
}
}
Already checked with SP Dispose checker but it says this (at MapWebs method line "node.tag = weblist[i]... and if statement")
Notes: Call to Microsoft.SharePoint.SPWebCollection.get_Item and no variable to catch return value
More Information: http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx#SPDisposeCheckID_130
I see two issues here:
You are disposing the SPWeb while iterating over the SPWeb.Webs, but you keep a reference on the TreeNode.Tag. When accessing the disposed SPWeb via the tag of the node SharePoint will "open" the web again. => Memory Leak
Since you are calling the MapWebs method recursive you have a lot of SPWeb objects opened simultaneously:
Root -> open
Child 1 -> open
Child 1.1 -> open
Child 1.1.1 -> open
Child 1.2
Child 1.3
Child 1.4
Child 2
Child 3
Related
I have started learning C# recently. Presently am working on creating "Windows Explorer".
Actual requirement is as follows
In list View Double Click function.
When I click on a folder in list view, it should display the files which are present in the folder in list view , but as per my code its being opened in another window.
Below is the code. Requesting for your help & guidance
alert(false);
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Configuration;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Security.Principal;
namespace New_Demo
{
public partial class WindowsExplorer : Form
{
string SelectedPath = string.Empty;
double size;
string filelength;
Login formPopup;
private FileAttributes attr;
public WindowsExplorer()
{
InitializeComponent();
PopulateTreeView();
}
private void PopulateTreeView()
{
TreeNode rootNode;
{
DirectoryInfo info = new DirectoryInfo(#"C:\Users\4076\Desktop\");
if (info.Exists)
{
rootNode = new TreeNode(info.Name);
rootNode.Tag = info;
GetDirectories(info.GetDirectories(), rootNode);
treeView.Nodes.Add(rootNode);
LoadFiles(info.FullName, rootNode);
}
else
MessageBox.Show("Please select a path");
}
}
private void LoadFiles(string dir, TreeNode td)
{
string[] Files = Directory.GetFiles(dir, "*.*");
// Loop through them to see files
foreach (string file in Files)
{
FileInfo fi = new FileInfo(file);
TreeNode tds = td.Nodes.Add(fi.Name);
tds.Tag = fi.FullName;
tds.StateImageIndex = 1;
//UpdateProgress();
}
}
private void GetDirectories(DirectoryInfo[] subDirs, TreeNode nodeToAddTo)
{
TreeNode aNode;
DirectoryInfo[] subSubDirs;
foreach (DirectoryInfo subDir in subDirs)
{
aNode = new TreeNode(subDir.Name, 0, 0);
aNode.Tag = subDir;
aNode.ImageKey = "folder";
subSubDirs = subDir.GetDirectories();
if (subSubDirs.Length != 0)
{
GetDirectories(subSubDirs, aNode);
}
nodeToAddTo.Nodes.Add(aNode);
}
}
private void treeView_NodeMouseClick_1(object sender, TreeNodeMouseClickEventArgs e)
{
TreeNode newSelected = e.Node;
listView.Items.Clear();
DirectoryInfo nodeDirInfo = (DirectoryInfo)newSelected.Tag;
if (!string.IsNullOrEmpty(nodeDirInfo.FullName.ToString()))
{
SelectedPath = nodeDirInfo.FullName.ToString();
}
ListViewItem.ListViewSubItem[] subItems;
ListViewItem item = null;
foreach (DirectoryInfo dir in nodeDirInfo.GetDirectories())
{
item = new ListViewItem(dir.Name, 0);
subItems = new ListViewItem.ListViewSubItem[]{new ListViewItem.ListViewSubItem(item, "File Folder"),
new ListViewItem.ListViewSubItem(item,dir.LastAccessTime.ToShortDateString())};
item.SubItems.AddRange(subItems);
listView.Items.Add(item);
item.BackColor = SystemColors.Window;
item.ForeColor = SystemColors.WindowText;
}
foreach (FileInfo file in nodeDirInfo.GetFiles())
{
long B = 0, KB = 1024, MB = KB * 1024, GB = MB * 1024;
string suffix = nameof(B);
if (file.Length >= GB)
{
size = Math.Round((double)file.Length / GB, 2);
suffix = nameof(GB);
filelength = size + " " + suffix;
}
else if (file.Length >= MB)
{
size = Math.Round((double)file.Length / MB, 2);
suffix = nameof(MB);
filelength = size + " " + suffix;
}
else if (file.Length >= KB)
{
size = Math.Round((double)file.Length / KB, 2);
suffix = nameof(KB);
filelength = size + " " + suffix;
}
item = new ListViewItem(file.Name, 1);
subItems = new ListViewItem.ListViewSubItem[]{ new ListViewItem.ListViewSubItem(item, "File"),
new ListViewItem.ListViewSubItem(item,file.LastAccessTime.ToShortDateString()),
new ListViewItem.ListViewSubItem(item,filelength.ToString())};
item.SubItems.AddRange(subItems);
listView.Items.Add(item);
}
listView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
}
private void listView_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (ListViewItem item in listView.Items)
{
item.BackColor = SystemColors.Window;
item.ForeColor = SystemColors.WindowText;
}
}
private void listView_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (listView.SelectedItems.Count > 0)
{
if (!string.IsNullOrEmpty(listView.SelectedItems[0].Text))
{
string SelectedPath_Combine = #"" + SelectedPath + "\\" + listView.SelectedItems[0].Text + "";
FileAttributes attr = File.GetAttributes(#"" + SelectedPath_Combine + "");
if ((attr & FileAttributes.Directory) != FileAttributes.Directory)
{
System.Diagnostics.Process.Start(SelectedPath_Combine);
}
else if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
{
// What to code here to display the files which are present in the folder??
}
}
}
}
You need to make three changes in the code to achieve what you want
Make PopulateTreeView method to take path argument from outside
If Directory info check is successful in above method, empty all nodes before adding new
Call PopulateTreeView with selectedCombine path
Here is updated code
private void PopulateTreeView(string path)
{
TreeNode rootNode;
{
DirectoryInfo info = new DirectoryInfo(path);
if (info.Exists)
{
treeView.Nodes.Clear();
rootNode = new TreeNode(info.Name);
rootNode.Tag = info;
GetDirectories(info.GetDirectories(), rootNode);
treeView.Nodes.Add(rootNode);
LoadFiles(info.FullName, rootNode);
}
else
MessageBox.Show("Please select a path");
}
}
private void ListView_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (listView.SelectedItems.Count > 0)
{
if (!string.IsNullOrEmpty(listView.SelectedItems[0].Text))
{
string SelectedPath_Combine = #"" + SelectedPath + "\\" + listView.SelectedItems[0].Text + "";
FileAttributes attr = File.GetAttributes(#"" + SelectedPath_Combine + "");
if ((attr & FileAttributes.Directory) != FileAttributes.Directory)
{
System.Diagnostics.Process.Start(SelectedPath_Combine);
}
else if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
{
PopulateTreeView(SelectedPath_Combine);
}
}
}
}
I made it so that you can open a dll and load it onto a listbox as a clickable item when once clicked, the plugin would load and you can execute that plugin.
I added a clear button that is suppose to clear the app of the currently loaded plugins.
It clears everything off the app but when I go to load them again, it loads duplicates.
How do I clear the assembly too so that when i reload a plugin, it will not duplicate??
Code Behind:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using PluginContracts;
using System;
using System.IO;
using Microsoft.Win32;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Diagnostics;
using System.Linq;
namespace SimplePlugin
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Dictionary<string, IPlugin> _Plugins; // move to class scope
public MainWindow()
{
InitializeComponent();
_Plugins = new Dictionary<string, IPlugin>();
}
private void AssembleComponents(object sender)
{
string selection = "";
if (sender is ListBox)
{
if (((ListBox)sender).SelectedValue != null)
selection = ((ListBox)sender).SelectedValue.ToString();
}
string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
DirectoryCatalog cat = new DirectoryCatalog(path);
//ICollection<IPlugin> plugins = PluginLoader.LoadPlugins("Plugins");
ICollection<IPlugin> plugins = GenericPluginLoader<IPlugin>.LoadPlugins("Plugins");
foreach (var item in plugins)
{
//add only if not already present
if (!_Plugins.ContainsKey(item.Name))
{
string dllName = GetDLLName(item.Name);
Button b = new Button()
{
Name = dllName.Replace(".", "").ToUpper(),
Content = item.Name,
Visibility = System.Windows.Visibility.Hidden
};
b.Click += b_Click;
PluginGrid.Children.Add(b);
_Plugins.Add(item.Name, item);
// this.PluginGrid.Children.Clear();
//by Vasey
}
}
// make visible the selected plugin button
foreach (var ctl in PluginGrid.Children)
{
if (ctl is Button)
{
Button button = (Button)ctl;
if (button.Name.Equals(selection.Replace(".", "").ToUpper()))
{
button.Visibility = System.Windows.Visibility.Visible;
}
else
{
button.Visibility = System.Windows.Visibility.Hidden;
}
}
}
}
private void b_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
if (b != null)
{
string key = b.Content.ToString();
if (_Plugins.ContainsKey(key))
{
IPlugin plugin = _Plugins[key];
plugin.Do();
}
}
}
private void addPlugin_Click(object sender, RoutedEventArgs e)
{
var fileDialog = new OpenFileDialog();
fileDialog.Multiselect = true;
fileDialog.Filter = "All files (*.*)|*.*|DLL files (*.dll)|*.dll|CS Files (*.cs)|*.cs";
if (fileDialog.ShowDialog() == true)
{
string filename = fileDialog.FileName;
var ext = System.IO.Path.GetExtension(filename);
// ListBox lbFiles = new ListBox();
//this.Controls.Add(lbFiles);
//lbFiles.Size = new System.Drawing.Size(200, 100);
//lbFiles.Location = new System.Drawing.Point(10, 10);
lbFiles.Items.Add(System.IO.Path.GetFileName(filename));
//
CopyToDir(filename);
}
}
private void CopyToDir(string filename)
{
// txtBox.Text = "Hello World";
string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
Console.WriteLine(path);
//Check the directory exists
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
try
{
FileInfo fi = new FileInfo(filename);
if (!File.Exists(System.IO.Path.Combine(path, fi.Name)))
{
File.Copy(fi.FullName, System.IO.Path.Combine(path, fi.Name));
}
}
catch (Exception ex)
{
throw ex;
}
}
// Get linkage between ListBox's DLL name list and the loaded plugin names
string GetDLLName(string name)
{
string ret = "";
name = name.Replace(" ", ""); // strip spaces
Assembly asm = AppDomain.CurrentDomain.GetAssemblies().
SingleOrDefault(assembly => assembly.GetName().Name == name);
if (asm != null)
{
ret = Path.GetFileName(asm.Location);
}
return ret;
}
private void lbFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
AssembleComponents(sender);
}
private void ClearBtn_Click(object sender, RoutedEventArgs e)
{
lbFiles.Items.Clear();
_Plugins = new Dictionary<string, IPlugin>();
}
}
}
I just had to add this function to the clearBtn method
//Clears the Assembly
this.PluginGrid.Children.Clear();
Before
private void ClearBtn_Click(object sender, RoutedEventArgs e)
{
lbFiles.Items.Clear();
_Plugins = new Dictionary<string, IPlugin>();
}
After
private void ClearBtn_Click(object sender, RoutedEventArgs e)
{
// Clears the ListBox
lbFiles.Items.Clear();
//Clears the Assembly
this.PluginGrid.Children.Clear();
//Loads next Assembly
_Plugins = new Dictionary<string, IPlugin>();
}
My program search for text inside files.
But what i want to do is to see the searching progress in real time.
I want to add the current file name search in to listView and also to display to a progressBar the percentages from 0 to 100%.
I added a backgroundworker but the way i'm using the ReportProgress is not working good. I need to wait for it to finish the foreach in the FindLines method and then only in the end i see the items in the listView and even then the items are a big mess.
This is the line that report:
backgroundWorker1.ReportProgress(0, fi.Name);
This is a screenshot of the items in the listView when the foreach is over:
What i want to do is to display the items adding to the listView in real time without waiting first to the operation over and also to add each item to a line and if a line is too long then later i will add a tip baloon or something. But now the listView look like a big mess.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
namespace Search_Text_In_Files
{
public partial class Form1 : Form
{
StreamWriter w = new StreamWriter(#"e:\textresults.txt");
public Form1()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync();
}
public List<string> FindLines(string DirName, string TextToSearch)
{
int counter = 0;
List<string> findLines = new List<string>();
DirectoryInfo di = new DirectoryInfo(DirName);
if (di != null && di.Exists)
{
if (CheckFileForAccess(DirName) == true)
{
foreach (FileInfo fi in di.EnumerateFiles("*", SearchOption.AllDirectories))
{
if (string.Compare(fi.Extension, ".cs", true) == 0)
{
backgroundWorker1.ReportProgress(0, fi.Name);
using (StreamReader sr = fi.OpenText())
{
string s = "";
while ((s = sr.ReadLine()) != null)
{
if (s.Contains(TextToSearch))
{
counter++;
findLines.Add(s);
}
}
}
}
}
}
w.Close();
}
return findLines;
}
private bool CheckForAccess(string PathName)
{
// Determine if the path is a file or a directory
if (File.Exists(PathName) == true)
return CheckFileForAccess(PathName);
if (Directory.Exists(PathName) == true)
return CheckFolderForAccess(PathName);
return false;
}
private bool CheckFileForAccess(string FileName)
{
FileSecurity fs = new FileSecurity(FileName, AccessControlSections.Access);
if (fs == null)
return false;
AuthorizationRuleCollection TheseRules = fs.GetAccessRules(true, true, typeof(NTAccount));
if (TheseRules == null)
return false;
return CheckACL(TheseRules);
}
private bool CheckFolderForAccess(string FolderName)
{
DirectoryInfo di = new DirectoryInfo(FolderName);
if (di == null)
return false;
DirectorySecurity acl = di.GetAccessControl(AccessControlSections.Access);
if (acl == null)
return false;
AuthorizationRuleCollection TheseRules = acl.GetAccessRules(true, true, typeof(NTAccount));
if (TheseRules == null)
return false;
return CheckACL(TheseRules);
}
private bool CheckACL(AuthorizationRuleCollection TheseRules)
{
foreach (FileSystemAccessRule ThisRule in TheseRules)
{
if ((ThisRule.FileSystemRights & FileSystemRights.Read) == FileSystemRights.Read)
{
if (ThisRule.AccessControlType == AccessControlType.Deny)
return false;
}
// Run as many other checks as you like
}
return true;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
FindLines(#"d:\c-sharp", "string s1 = treeView1.SelectedNode.Tag as string;");
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
listView1.Items.Add(e.UserState.ToString());
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
}
}
This is a screenshot of the items in the listView when the foreach is
over: What i want to do is to display the items adding to the listView
in real time without waiting first to the operation over and also to
add each item to a line and if a line is too long then later i will
add a tip baloon or something. But now the listView look like a big
mess.
Did you try setting your Listview's view property to "List" ? That should display the file names in individual lines.
I think you should look into ObservableCollection(T). The collection fires events when items are added to it, and the UI element should automatically detect these changes and update the view.
At least that is how it works in WPF, but i think it should work as well in WinForms.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Iam trying to get all drives, folders, subfolders and files in treeview control using winforms. I have seen the following article.
http://codehill.com/2013/06/list-drives-and-folders-in-a-treeview-using-c/
but this only shows drives, folders and sub folders but not the files containing in these folders.
Please anyone help and guide that how can i view all these files under these folders in treeview, thanks in advance.
EDIT:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GetDrives
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
//get a list of the drives
string[] drives = Environment.GetLogicalDrives();
foreach (string drive in drives)
{
DriveInfo di = new DriveInfo(drive);
int driveImage;
switch (di.DriveType) //set the drive's icon
{
case DriveType.CDRom:
driveImage = 3;
break;
case DriveType.Network:
driveImage = 6;
break;
case DriveType.NoRootDirectory:
driveImage = 8;
break;
case DriveType.Unknown:
driveImage = 8;
break;
default:
driveImage = 2;
break;
}
TreeNode node = new TreeNode(drive.Substring(0, 1), driveImage, driveImage);
node.Tag = drive;
if (di.IsReady == true)
node.Nodes.Add("...");
dirsTreeView.Nodes.Add(node);
}
}
private void dirsTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
if (e.Node.Nodes.Count > 0)
{
if (e.Node.Nodes[0].Text == "..." && e.Node.Nodes[0].Tag == null)
{
e.Node.Nodes.Clear();
//get the list of sub direcotires
string[] dirs = Directory.GetDirectories(e.Node.Tag.ToString());
foreach (string dir in dirs)
{
DirectoryInfo di = new DirectoryInfo(dir);
TreeNode node = new TreeNode(di.Name, 0, 1);
try
{
//keep the directory's full path in the tag for use later
node.Tag = dir;
//if the directory has sub directories add the place holder
if (di.GetDirectories().Count() > 0)
node.Nodes.Add(null, "...", 0, 0);
foreach (var file in di.GetFiles())
{
TreeNode n = new TreeNode(file.Name, 13, 13);
node.Nodes.Add(n);
}
}
catch (UnauthorizedAccessException)
{
//display a locked folder icon
node.ImageIndex = 12;
node.SelectedImageIndex = 12;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "DirectoryLister",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
e.Node.Nodes.Add(node);
}
}
}
}
}
}
}
I have now updated my code in application and using only one treeview, but the problem still exists. You can see in image, in my C drive i have a file name "courses outline.html" and ab.txt which are not showing in application, which i need to see. Please see iamge below to easily understand my requirement.
Change the code in the try block (from: List Drives and Folders in a TreeView Using C#) as following:
EDIT:
Added following code, because the files of the root-directory were ignored:
//add files of rootdirectory
DirectoryInfo rootDir = new DirectoryInfo(e.Node.Tag.ToString());
foreach (var file in rootDir.GetFiles())
{
TreeNode n = new TreeNode(file.Name, 13, 13);
e.Node.Nodes.Add(n);
}
Full class:
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
if (e.Node.Nodes.Count > 0)
{
if (e.Node.Nodes[0].Text == "..." && e.Node.Nodes[0].Tag == null)
{
e.Node.Nodes.Clear();
//get the list of sub direcotires
string[] dirs = Directory.GetDirectories(e.Node.Tag.ToString());
//add files of rootdirectory
DirectoryInfo rootDir = new DirectoryInfo(e.Node.Tag.ToString());
foreach (var file in rootDir.GetFiles())
{
TreeNode n = new TreeNode(file.Name, 13, 13);
e.Node.Nodes.Add(n);
}
foreach (string dir in dirs)
{
DirectoryInfo di = new DirectoryInfo(dir);
TreeNode node = new TreeNode(di.Name, 0, 1);
try
{
//keep the directory's full path in the tag for use later
node.Tag = dir;
//if the directory has sub directories add the place holder
if (di.GetDirectories().Count() > 0)
node.Nodes.Add(null, "...", 0, 0);
foreach (var file in di.GetFiles())
{
TreeNode n = new TreeNode(file.Name, 13, 13);
node.Nodes.Add(n);
}
}
catch (UnauthorizedAccessException)
{
//display a locked folder icon
node.ImageIndex = 12;
node.SelectedImageIndex = 12;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "DirectoryLister",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
e.Node.Nodes.Add(node);
}
}
}
}
}
This look like following picture:
You can use the enumerate files method to get the name of each file inside a directory location.
string sourceDirectory = #"C:\current";
var files = Directory.EnumerateFiles(sourceDirectory);
foreach (string file in files)
{
// Do Something with file
}
I found this code online. It works, but for some reason it loads the file directory twice.
namespace DockSample.Controls
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using Microsoft.VisualBasic.FileIO;
using DockSample;
//TODO: Add options for filtering by robot
public class SolutionExplorer : TreeView
{
public SolutionExplorer()
{
this.BeforeExpand += customBeforeExpand;
this.Nodes.Clear();
CreateTree(this);
}
private bool CreateTree(TreeView treeView)
{
bool returnValue = false;
try
{
// Create Desktop
TreeNode desktop = new TreeNode();
// desktop.Text = "Desktop";
// desktop.Tag = "Desktop";
// desktop.Nodes.Add("");
// treeView.Nodes.Add(desktop);
// Get driveInfo
foreach (DriveInfo drv in DriveInfo.GetDrives())
{
TreeNode fChild = new TreeNode();
if (drv.DriveType == DriveType.CDRom)
{
fChild.ImageIndex = 1;
fChild.SelectedImageIndex = 1;
}
else if (drv.DriveType == DriveType.Fixed)
{
fChild.ImageIndex = 0;
fChild.SelectedImageIndex = 0;
}
fChild.Text = drv.Name;
fChild.Nodes.Add("");
treeView.Nodes.Add(fChild);
returnValue = true;
}
}
catch
{
returnValue = false;
}
return returnValue;
}
/* Method :EnumerateDirectory
* Author : Chandana Subasinghe
* Date : 10/03/2006
* Discription : This is use to Enumerate directories and files
*
*/
public TreeNode EnumerateDirectory(TreeNode parentNode, List<string> thisFilter)
{
try
{
DirectoryInfo rootDir;
// To fill Desktop
Char[] arr = { '\\' };
string[] nameList = parentNode.FullPath.Split(arr);
string path = "";
if (nameList.GetValue(0).ToString() == "Desktop")
{
path = SpecialDirectories.Desktop + "\\";
for (int i = 1; i < nameList.Length; i++)
{
path = path + nameList[i] + "\\";
}
rootDir = new DirectoryInfo(path);
}
// for other Directories
else
{
rootDir = new DirectoryInfo(parentNode.FullPath + "\\");
}
parentNode.Nodes[0].Remove();
foreach (DirectoryInfo dir in rootDir.GetDirectories())
{
TreeNode node = new TreeNode();
node.Text = dir.Name;
node.Nodes.Add("");
parentNode.Nodes.Add(node);
}
//Fill files
foreach (FileInfo file in rootDir.GetFiles())
{
if (isValidFilter(getExtention(file.Name)))
{
TreeNode node = new TreeNode();
node.Text = file.Name;
node.ImageIndex = 2;
node.SelectedImageIndex = 2;
parentNode.Nodes.Add(node);
}
}
}
catch
{
}
return parentNode;
}
private bool isValidFilter(string ext)
{
bool result = false;
foreach(string s in filter)
{
if (ext == s)
result = true;
}
return result;
}
private string getExtention(string filename)
{
return filename.Substring(filename.IndexOf("."));
}
private void customBeforeExpand(object sender, TreeViewCancelEventArgs e)
{
if (e.Node.Nodes[0].Text == "")
{
TreeNode node = this.EnumerateDirectory(e.Node,filter);
}
}
private List<string> filter = new List<string>();
public List<string> Filter
{
get { return filter; }
set { filter = value; }
}
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
}
}
The constructor of your control runs at both design time and run time. So as soon as you drop the control on the form, it will fill the tree view. Problem is, the nodes will be serialized to InitializeComponent(). Take a look at the Designer.cs file for your form, you'll find them back there. When you run the form, the constructor runs again, doubling the list.
You need to prevent the constructor from adding the nodes at design time. That's a bit difficult to do, you'd normally use the DesignMode property but it isn't set to true yet in the constructor. Do it like this instead:
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
if (!DesignMode && treeView.Nodes.Count == 0) {
CreateTree(this);
}
}
Or do it explicitly by adding a public method that you call in the form's constructor or OnLoad method. Which is rather wise, you might want to catch exceptions. Always likely when you tinker with the file system.