问题
Have a look at this screenshot first to see what happens:
What you can see on this screenshot is what I have done already.. But I want to add a few things more.
Right now by clicking at the "Add to list" button all files with their full path are stored in List A. Their file names are stored in List B. And heres the code for it:
if (type == "folder")
{
string listPath = this.configsPath.Text;
string[] filesToList = System.IO.Directory.GetFiles(listPath, "*.*", System.IO.SearchOption.AllDirectories);
foreach (string file in filesToList)
{
if (!configsChkList.Items.Contains(file))
{
configsChkList.Items.Add(file, false);
configsDestList.Items.Add(Path.GetFileName(file));
}
}
}
I want List b to also store their path relative to the path specified in the input field.. The last three entries in List A as an example are in a sub-directory called "undermappe", but since I use Path.GetFileName to store the entries in List B the sub-directory does not get viewed.. How can I do this?
And then another thing. The sub-directories should also be stored in the ComboBox on top, but only the directories not the names! How can I do this ?
回答1:
I didn't write this (so I won't take credit), but this function returns the relative path:
/// <summary>
/// method to provide a relative path from a directory to a path
/// </summary>
/// <param name="fromDirectory">the starting folder</param>
/// <param name="toPath">the path that will be pointed to</param>
/// <returns>string</returns>
public static string RelativePathTo(string fromDirectory, string toPath)
{
if (fromDirectory == null)
{
throw new ArgumentNullException("fromDirectory");
}
if (toPath == null)
{
throw new ArgumentNullException("fromDirectory");
}
if (System.IO.Path.IsPathRooted(fromDirectory) && System.IO.Path.IsPathRooted(toPath))
{
if (string.Compare(System.IO.Path.GetPathRoot(fromDirectory)
, System.IO.Path.GetPathRoot(toPath), true) != 0)
{
throw new ArgumentException(
String.Format("The paths '{0} and '{1}' have different path roots."
, fromDirectory
, toPath));
}
}
StringCollection relativePath = new StringCollection();
string[] fromDirectories = fromDirectory.Split(System.IO.Path.DirectorySeparatorChar);
string[] toDirectories = toPath.Split(System.IO.Path.DirectorySeparatorChar);
int length = Math.Min(fromDirectories.Length, toDirectories.Length);
int lastCommonRoot = -1;
// find common root
for (int x = 0; x < length; x++)
{
if (string.Compare(fromDirectories[x], toDirectories[x], true) != 0)
{
break;
}
lastCommonRoot = x;
}
if (lastCommonRoot == -1)
{
throw new ArgumentException(
string.Format("The paths '{0} and '{1}' do not have a common prefix path."
, fromDirectory
, toPath));
}
// add relative folders in from path
for (int x = lastCommonRoot + 1; x < fromDirectories.Length; x++)
{
if (fromDirectories[x].Length > 0)
{
relativePath.Add("..");
}
}
// add to folders to path
for (int x = lastCommonRoot + 1; x < toDirectories.Length; x++)
{
relativePath.Add(toDirectories[x]);
}
// create relative path
string[] relativeParts = new string[relativePath.Count];
relativePath.CopyTo(relativeParts, 0);
string newPath = string.Join(System.IO.Path.DirectorySeparatorChar.ToString(), relativeParts);
return newPath;
}
I'm sorry but I don't understand your second request, but if you are asking how to get the name of a directory it is quite easy with DirectoryInfo
DirectoryInfo di = new DirectoryInfo(@"c\temp\en");
string s = di.Name;
回答2:
I want List b to also store their path relative to the path specified in the input field.. The last three entries in List A as an example are in a sub-directory called "undermappe", but since I use Path.GetFileName to store the entries in List B the sub-directory does not get viewed.. How can I do this?
Just remove the first X characters where X is the Length of the path in the input field. This can be done with Substring(); something like:
string relativePath = stringFromListBox.Substring(stringFromInputField.Length + 1);
The "+ 1" should get rid of the leading slash.
回答3:
For the second part of your question, about the paths in the combo box, you can take each full file name, and use Path.GetDirectoryName() to get just the directory.
var files = new []{@"f:\Noter\Test\2004 ABC Musik.txt",@"f:\Noter\Test\activision_support.txt",@"f:\Noter\Test\Alberte.txt",@"F:\Noter\Test\undermappe\steam password!.txt"};
var folders = files.Select(f => System.IO.Path.GetDirectoryName(f)).Distinct().ToList();
If you want just the folders under the main 'F:\noter\test'
folder, then just use your relative path code on them from answers for the first part of your question
回答4:
**Hi.
try this example , i think this is what you need , 100% working:**
System.String basefolder = "NASSIM\\LOUCHANI\\";
foreach (String file in Directory.GetFiles(basefolder,"*.*"))
{
comboBox1.Items.Add(Path.GetFileNameWithoutExtension(file));
//Load file name without extension / path.
}
来源:https://stackoverflow.com/questions/19258504/get-files-from-folders-to-list-add-subdirectories-to-dropdown-and-list-filename