what might be causing this to fill this treeview multiple times? - c#

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.

Related

Getting warning CS0469 how to solve? [duplicate]

I've been searching for answers everywhere and I can't seem to solve mine. Anyone know a solution for this? I'm getting the following errors:
Line 25: Field 'Champion_Item_List_Downloader.MainForm.championsList' is never assigned to, and will always have its default value null (CS0649)
Line 26: Field 'Champion_Item_List_Downloader.MainForm.rolesList' is never assigned to, and will always have its default value null (CS0649)
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.ComponentModel;
namespace Champion_Item_List_Downloader
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
const string listFile = "Lists.txt";
private System.Collections.Generic.List<string> championsList;
private System.Collections.Generic.List<string> rolesList;
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
loadList(listFile);
}
public void loadList(string file){
try {
using (StreamReader r = new StreamReader(file))
{
string line;
bool isChamp = false;
while ((line = r.ReadLine()) != null)
{
if (line == #"[Champions]") {
isChamp = true;
}
if(line != #"[Champions]" && line != #"[Types]" && line != "")
{
if(isChamp == true){
championsList.Add(line);
} else {
rolesList.Add(line);
}
}
}
}
} catch (Exception) {
}
}
public void loadStringList(string file, List<string> list){
try {
using (StreamReader r = new StreamReader(file))
{
string line;
while ((line = r.ReadLine()) != null)
{
list.Add(line);
}
}
} catch (Exception) {
}
}
void Btn_DownloadClick(object sender, EventArgs e)
{
WebClient webClient = new WebClient();
progressBar.Maximum = championsList.Count * rolesList.Count;
int count = 0;
progressBar.Value = 0;
string fileName = "";
string url = "";
string path = "";
foreach (string c in championsList)
{
foreach (string r in rolesList)
{
try {
fileName = c + #"_" + r + #"_scrape.json";
url = #"http://www.lolflavor.com/champions/" + c + #"/Recommended/" + fileName;
path = #"Champions\" + c + #"\Recommended\";
Directory.CreateDirectory(path);
webClient.DownloadFile(new Uri(url), path + fileName);
count++;
progressBar.Value = count;
} catch (Exception) {
}
}
}
progressBar.Value = progressBar.Maximum;
MessageBox.Show("Download completed!\n" + count.ToString() + " item lists successfully downloaded.");
}
void MainFormLoad(object sender, System.EventArgs e)
{
throw new NotImplementedException();
}
}
}
You have not initialized your lists anywhere.
Try initializing them where they are declared:
private System.Collections.Generic.List<string> championsList = new System.Collections.Generic.List<string>();
private System.Collections.Generic.List<string> rolesList = new System.Collections.Generic.List<string>();
Or within the constructor:
private System.Collections.Generic.List<string> championsList;
private System.Collections.Generic.List<string> rolesList;
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
// loadList uses these lists so they should be initialized before the call to loadList to avoid a NullReferenceException.
championsList = new System.Collections.Generic.List<string>();
rolesList = new System.Collections.Generic.List<string>();
loadList(listFile);
}
Or lazily at the time they are needed:
private System.Collections.Generic.List<string> championsList;
private System.Collections.Generic.List<string> rolesList;
public void loadList(string file){
if (championsList == null) championsList = new System.Collections.Generic.List<string>();
if (rolesList == null) rolesList = new System.Collections.Generic.List<string>();
try {
using (StreamReader r = new StreamReader(file))
{
...
}
} catch (Exception) {
}
}
void Btn_DownloadClick(object sender, EventArgs e)
{
WebClient webClient = new WebClient();
if (championsList == null) championsList = new System.Collections.Generic.List<string>();
if (rolesList == null) rolesList = new System.Collections.Generic.List<string>();
progressBar.Maximum = championsList.Count * rolesList.Count;
int count = 0;
progressBar.Value = 0;
string fileName = "";
string url = "";
string path = "";
foreach (string c in championsList)
{
foreach (string r in rolesList)
{
...
}
}
progressBar.Value = progressBar.Maximum;
MessageBox.Show("Download completed!\n" + count.ToString() + " item lists successfully downloaded.");
}
P.S. because you already have using System.Collections.Generic declared, you could write it more simply as:
private List<string> championsList = new List<string>();
private List<string> rolesList = new List<string>();
There is never a call to championsList = new System.Collections.Generic.List<string>().
Thus it's never initialized

C#. How to open a folder in list view by double click

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);
}
}
}
}

My method did not add my file into my list although no error

This is my class that after each file choose add the file to my list and from the main form raise event that update my ListBox and add the file into my ListBox.
when i am choosing 2 files i can see (with the debugger) that the add method add the first file and my list updated but after the second file pass the add method the list.count remained still 1.
public class ListboxFile
{
public delegate void OnFileAdd(string file);
public event OnFileAdd OnFileAddEvent;
private static List<string> _files;
public ListboxFile()
{
_files = new List<string>();
}
public void add(string file)
{
_files.Add(file);
OnFileAddEvent(file);
}
public void remove(string file)
{
if (_files.Contains(file))
{
_files.Remove(file);
}
}
public void clear()
{
_files.Clear();
}
public List<string> list
{
get { return _files; }
}
}
from the main form (add files button click):
private void btnAddfiles_Click(object sender, EventArgs e)
{
#region file filter
string fileToAdd = string.Empty;
System.IO.Stream stream;
OpenFileDialog thisDialog = new OpenFileDialog();
thisDialog.InitialDirectory = (lastPath.Length > 0 ? lastPath : "c:\\");
thisDialog.Filter = "(*.snoop, *.pcap, *.cap, *.net, *.pcapng, *.5vw, *.bfr, *.erf, *.tr1)" +
"|*.snoop; *.pcap; *.cap; *.net; *.pcapng; *.5vw; *.bfr; *.erf; *.tr1|" + "All files (*.*)|*.*";
thisDialog.FilterIndex = 1;
thisDialog.RestoreDirectory = false;
thisDialog.Multiselect = true;
thisDialog.Title = "Please Select Source File";
#endregion
if (thisDialog.ShowDialog() == DialogResult.OK)
{
if (thisDialog.FileNames.Length > 0)
{
lastPath = Path.GetDirectoryName(thisDialog.FileNames[0]);
}
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork +=
(s3, e3) =>
{
foreach (String file in thisDialog.FileNames)
{
try
{
if ((stream = thisDialog.OpenFile()) != null)
{
int numberOfFiles = thisDialog.SafeFileNames.Length;
using (stream)
{
ListboxFile lbf = new ListboxFile();
lbf.OnFileAddEvent += lbf_OnFileAddEvent;
lbf.checkFile(file);
lastPath = Path.GetDirectoryName(thisDialog.FileNames[0]);
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
};
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
(s3, e3) =>
{
});
backgroundWorker.RunWorkerAsync();
}
}
private void lbf_OnFileAddEvent(string file)
{
if (InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
listBoxFiles.Items.Add(file);
, listBoxFiles.Items.Count.ToString("#,##0")));
if (listBoxFiles.Items.Count != 0)
listBoxFiles.SetSelected(listBoxFiles.Items.Count - 1, true);
});
}
else
{
listBoxFiles.Items.Add(file);
if (listBoxFiles.Items.Count != 0)
listBoxFiles.SetSelected(listBoxFiles.Items.Count - 1, true);
}
}
You declare and initialize the instance of ListBoxFile inside the foreach loop.
At every loop you reinitialize the instance and thus you loose the previous add
A fast fix, move the declaration and initialization of the ListboxFile instance outside the loop (also the subscription to the event)
.....
ListboxFile lbf = new ListboxFile();
lbf.OnFileAddEvent += lbf_OnFileAddEvent;
foreach (String file in thisDialog.FileNames)
{
.....
and by the way, you call lbf.checkFile(file);, did you mean lbf.Add(file) right?
You are calling lbf.checkFile(file); but I do not see that method in your class definition. Maybe inside that method you are not firing OnFileAddEvent?

Too Much Memory Usage for Windows form Application

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

Trouble getting my button to call my class

I have a Windows Form application. What this application does, is let the user browse to a drive/folder they wish to have files renamed for. This app renames files that have "invalid" characters (that are defined in a RegEx pattern).
What i want to happen here is, after the user decides which drive/folder to use, a datagridview pops up showing the user files in the drive/folder that are going to be renamed. The user then clicks a button to actually rename the files. I'm having trouble though getting the code for my button in DriveRecursion_Results.cs set up. Can anybody help me? Code plz -- i'm extremely new to this and need syntax to look at to understand.
Form1 code:
namespace FileMigration2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
FolderSelect("Please select:");
}
public string FolderSelect(string txtPrompt)
{
//Value to be returned
string result = string.Empty;
//Now, we want to use the path information to population our folder selection initial location
string initialPathDir = (#"C:\");
System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(initialPathDir);
FolderBrowserDialog FolderSelect = new FolderBrowserDialog();
FolderSelect.SelectedPath = info.FullName;
FolderSelect.Description = txtPrompt;
FolderSelect.ShowNewFolderButton = true;
if (FolderSelect.ShowDialog() == DialogResult.OK)
{
string retPath = FolderSelect.SelectedPath;
if (retPath == null)
{
retPath = "";
}
DriveRecursion_Results dw = new DriveRecursion_Results();
dw.Show();
dw.DriveRecursion(retPath);
result = retPath;
}
return result;
}
}
}
DriveRecursion_Results.cs code: [the button is in here that i need help with!]
namespace FileMigration2
{
public partial class DriveRecursion_Results : Form
{
public DriveRecursion_Results()
{
InitializeComponent();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
public void DriveRecursion(string retPath)
{
//recurse through files. Let user press 'ok' to move onto next step
// string[] files = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
string pattern = " *[\\~#%&*{}/<>?|\"-]+ *";
//string replacement = "";
Regex regEx = new Regex(pattern);
string[] fileDrive = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
List<string> filePath = new List<string>();
dataGridView1.Rows.Clear();
try
{
foreach (string fileNames in fileDrive)
{
if (regEx.IsMatch(fileNames))
{
string fileNameOnly = Path.GetFileName(fileNames);
string pathOnly = Path.GetDirectoryName(fileNames);
DataGridViewRow dgr = new DataGridViewRow();
filePath.Add(fileNames);
dgr.CreateCells(dataGridView1);
dgr.Cells[0].Value = pathOnly;
dgr.Cells[1].Value = fileNameOnly;
dataGridView1.Rows.Add(dgr);
filePath.Add(fileNames);
}
else
{
DataGridViewRow dgr2 = new DataGridViewRow();
dgr2.Cells[0].Value = "No Files To Clean Up";
dgr2.Cells[1].Value = "";
}
}
}
catch (Exception e)
{
StreamWriter sw = new StreamWriter(retPath + "ErrorLog.txt");
sw.Write(e);
}
}
private void button1_Click(object sender, EventArgs e)
{
//What do i type in here to call my FileCleanUp method???
}
}
SanitizeFileNames.cs code:
namespace FileMigration2
{
public class SanitizeFileNames
{
public static void FileCleanup(List<string>filePath)
{
string regPattern = "*[\\~#%&*{}/<>?|\"-]+*";
string replacement = "";
Regex regExPattern = new Regex(regPattern);
foreach (string files2 in filePath)
{
try
{
string filenameOnly = Path.GetFileName(files2);
string pathOnly = Path.GetDirectoryName(files2);
string sanitizedFileName = regExPattern.Replace(filenameOnly, replacement);
string sanitized = Path.Combine(pathOnly, sanitizedFileName);
//write to streamwriter
System.IO.File.Move(files2, sanitized);
}
catch (Exception ex)
{
//write to streamwriter
}
}
}
}
}
}
Any help is appreciated!
Thanks :)
Put
public partial class DriveRecursion_Results : Form {
List<string> filePath;
and in driveRecursion method, just use
filePath = new List<string>();
and in the action button method, why don't you do
if(filePath != null)
SanitizeFileNames.FileCleanup(filePath);
You call filePath.Add twice ?
Your 'else' is in the wrong place too.
What is dgr2?

Categories