【问题标题】:Generated a list of filenames, but no file paths生成文件名列表,但没有文件路径
【发布时间】:2012-08-09 15:04:27
【问题描述】:

我有一个列表框,它显示一组引用文本文件的文件名。我认为显示完整路径在美学上没有吸引力,所以我使用Path.GetFileName 将目录部分截掉。

但是现在当用户选择要打开的特定文件名时,我已经丢失了路径。这些文件可以位于本地计算机上的任何位置(目前)。

如何使用列表框来显示漂亮的文件名,同时参考实际文件?

编辑:我喜欢为每个列表框项创建一个自定义包装类的想法。

【问题讨论】:

  • 如果有两个文件名相同但路径不同会怎样?用户如何知道选择其中一个?
  • 交叉手指,希望一切顺利。我将提供一个显示完整路径的选项。

标签: c# winforms


【解决方案1】:

我过去所做的是为我想在 ListBox 中显示的对象创建一个包装类。在此类中,将ToString 覆盖为要在 ListBox 中显示的字符串。

当您需要获取所选项目的详细信息时,将其强制转换为包装类并提取您需要的数据。

这是一个丑陋的例子:

class FileListBoxItem
{
    public string FileFullname { get; set; }
    public override string ToString() {
        return Path.GetFileName(FileFullname);
    }
}

用 FileListBoxItems 填充您的 ListBox:

listBox1.Items.Add(new FileListBoxItem { FileFullname = @"c:\TestFolder\file1.txt" })

像这样取回所选文件的全名:

var fileFullname = ((FileListBoxItem)listBox1.SelectedItem).FileFullname;

编辑
@user1154664 在对您最初的问题的评论中提出了一个很好的观点:如果显示的文件名相同,用户将如何区分两个 ListBox 项?

这里有两个选项:

同时显示每个 FileListBoxItem 的父目录

为此,请将ToString 覆盖更改为:

public override string ToString() {
    var di = new DirectoryInfo(FileFullname);
    return string.Format(@"...\{0}\{1}", di.Parent.Name, di.Name);
} 

在工具提示中显示 FileListBoxItem 的完整路径

为此,将 ToolTip 组件拖放到表单上,并为 ListBox 添加一个 MouseMove 事件处理程序,以检索用户将鼠标悬停在 FileLIstBoxItem 上的 FileFullname 属性值。

private void listBox1_MouseMove(object sender, MouseEventArgs e) {
    string caption = "";

    int index = listBox1.IndexFromPoint(e.Location);
    if ((index >= 0) && (index < listBox1.Items.Count)) {
        caption = ((FileListBoxItem)listBox1.Items[index]).FileFullname;
    }
    toolTip1.SetToolTip(listBox1, caption);
}

当然,您可以将第二个选项与第一个选项一起使用。

Source 用于 ListBox 中的工具提示(已接受的答案,将代码重新格式化为我喜欢的风格)。

【讨论】:

    【解决方案2】:

    如果使用 WPF,请使用 ListBoxItem.Tag 存储每个项目的完整路径。或者,如果使用 WinForms,您可以创建一个自定义类来存储完整路径,但会覆盖 object.ToString() 以便只显示文件名。

    class MyPathItem
    {
        public string Path { get; set; }
        public override string ToString() 
        {
            return System.IO.Path.GetFileName(Path);
        }
    }
    
    ...
    
    foreach (var fullPath in GetFullPaths())
    {
        myListBox.Add(new MyPathItem { Path = fullPath });
    }
    

    【讨论】:

    • 我讨厌人们开始使用 Tag 属性作为他们的个人废话桶。我已经看到代码由于缺乏对该属性的纪律而失败了很多次,这是没有其他选择的日子遗留下来的一种老式做法。
    【解决方案3】:

    我这样做

    public class ListOption
    {
       public ListOption(string text, string value)
       {
          Value = value;
          Text = text;
       }
    
       public string Value { get; set; }
       public string Text { get; set; }
    }
    

    然后创建我的列表

    List<ListOption> options = new List<ListOption>()
    For each item in files
       options.Add(new ListOption(item.Name, item.Value));
    Next
    

    绑定我的列表

    myListBox.ItemSource = options;
    

    然后获取我的值或文本

    protected void List_SelectionChanged(...)
    {
       ListOption option = (ListOption) myListBox.SelectedItem;
       doSomethingWith(option.Value);
    }
    

    这里的想法是主要的

    【讨论】:

      【解决方案4】:

      我个人不同意你认为这对用户来说是丑陋的观点。显示完整路径可为用户提供明确的详细信息,并使他们对自己的选择或所做的事情充满信心。

      我会使用Dictionary,使用项索引作为键,使用此列表项的完整路径作为值。

      Dictionary<int, string> pathDict = new Dictionary<int, string>();
      pathDict.Add(0, "C:\SomePath\SomeFileName.txt");
      ...
      

      以上可能是使用item.Tag 属性的最佳方式...

      我希望这会有所帮助。

      【讨论】:

      • 我想我总是可以提供一个选项来显示或隐藏目录路径,以防用户喜欢它们。
      猜你喜欢
      • 2016-09-19
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      • 2021-05-13
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      相关资源
      最近更新 更多