简体   繁体   中英

How to get actual path of a file listed in listbox?

I have a listbox which lists certain files from a certain directory. I added a messagebox which would show me the path of the file when i click on any list item. But when I click on any filename in the listbox, instead of showing the actual path, it shows the project file path.

Following is my code:

 private void btnrecprefresh_Click(object sender, EventArgs e)
    {
        string[] files = Directory.GetFiles(@"C:\testt", "*.txt", SearchOption.AllDirectories);

        foreach (string f in files)
        {
            string modelpath = Path.GetFullPath(f);
            string entry = Path.GetFileName(f);
            Listbox.Items.Add(entry);
        }
    }

    private void Listbox_SelectedIndexChanged(object sender, EventArgs e)
    {

        string selectedItems = Listbox.SelectedItems.ToString();
        string all = Path.GetFullPath(selectedItems);
        MessageBox.Show(all);
    }

Instead of showing the path as C:\\testt\\xyz.txt, it shows the path as C:\\Users\\Production\\Desktop\\Project1\\bin\\Release\\System.Windows.Forms.ListBox+SelectedObjectCollection

Edit for abbas:

public frmMain()
{
    InitializeComponent();
    Listbox.DisplayMember = "Title";
    Listbox.ValueMember = "Path";
}

public class FileItem
{
    public string Title { get; set; }
    public string Path { get; set; }
}

private void btnrecprefresh_Click(object sender, EventArgs e)
{
    string[] files = Directory.GetFiles(@"C:\testt", "*.txt", SearchOption.AllDirectories);

    foreach (string f in files)
    {
        var fileItem = new FileItem { Title = Path.GetFileName(f), Path = Path.GetFullPath(f) };
        Listbox.Items.Add(fileItem);
    }
}

private void Listbox_SelectedIndexChanged(object sender, EventArgs e)
{
    var selectedItems = ListBox1.SelectedItems.Cast<FileItem>();
    var all = string.Join(Environment.NewLine, selectedItems.Select(x => x.Path));
    MessageBox.Show(all);
}

The problem:

In the following line:

string selectedItems = Listbox.SelectedItems.ToString();

All you're doing is calling the ToString on the object. Getting the path of that object will naturally give you the C:\\Users\\... path.

Solution:

A way of achieving what you want, is to create a class that serves as a container with the information you need:

public class FileItem
{
    public string Title { get; set; }
    public string Path { get; set; }
}

Then, you fill the listbox with the path and title of the file when you have read the folder:

string[] files = Directory.GetFiles(@"C:\Temp", "*.txt", SearchOption.AllDirectories);

foreach (string f in files)
{
    var fileItem = new FileItem { Title = Path.GetFileName(f), Path = Path.GetFullPath(f) };
    listBox1.Items.Add(fileItem);
}

In the constructor of the form, add following lines:

listBox1.DisplayMember = "Title";
listBox1.ValueMember = "Path";

The string values correspond to the properties in the FileItem class. In the changed event of the listbox, change your code to following:

var selectedItems = listBox1.SelectedItems.Cast<FileItem>();
var all = string.Join(Environment.NewLine, selectedItems.Select(x => x.Path));
MessageBox.Show(all);

This creates a string with all the paths of the files that are selected in the listbox.

Example output:

在此处输入图片说明

The Path.GetFullPath method returns the current directory path if only the name of file is supplied:

This method uses current directory and current volume information to fully qualify path. If you specify a file name only in path, GetFullPath returns the fully qualified path of the current directory.

This is the reason why in your Listbox_SelectedIndexChanged method current directory path is returned.

Instead you should save the full path of the file separately from the text of the list box items and retrieve it in your Listbox_SelectedIndexChanged method:

// btnrecprefresh_Click method
string[] files = Directory.GetFiles(@"C:\test", "*.txt", SearchOption.AllDirectories);
foreach (string f in files)
{
    string entry = Path.GetFileName(f);
    var item = new ListBoxItem() { Content = entry, Tag = f };
    listbox.Items.Add(item);
}

// Listbox_SelectedIndexChanged method
var selectedItem = listbox.SelectedItem as ListBoxItem;
string path = selectedItem.Tag.ToString();
MessageBox.Show(path);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM