String.Format 是否可以在 XAML 中显示 Path 字符串的文件名

String.Format Is it possible to display file name for Path string in XAML

大家好,我是 C# 和 WPF 的新手。以下只是未经测试的示例。

假设我有

String path1 = "C:\Users\user\Desktop\File.ext"
String path2 = "C:\temp\text.txt"

String.Format(path1.Substring(path1.LastIndexOf('\')+1))
String.Format(path2.Substring(path1.LastIndexOf('\')+1))

我想在不更改原始字符串的情况下从路径中获取文件名,我想最好在 XAML 中执行此操作或执行值转换器。

我正在研究这个问题,想知道我是应该在一个 Observable 集合和 ListView 之间做一个值转换器,还是只坚持使用两个列表。一种在模型中手动包含文件路径,在 ListView 中显示文件名并分别更新两者(当前方法)。

我的数据模型

private List<String> AttachedFiles;
public ObservableCollection<String> fileNames { get; set; }

    public void addFilePath(String filePath) {
        this.AttachedFiles.Add(filePath);
    }

    public void removeFilePath(String filePath)
    {
        this.AttachedFiles.Remove(filePath);
    }

xaml

<ListView x:Name="DropList" ItemsSource="{Binding fileNames}"

我只包含了很少的代码,只是为了在考虑重构时给出一个想法。我可以在 String.Format 中使用字符串方法在 XAML 中播放,这样它在模型中仍将具有原始文件路径值,或者 String.Format 是否有一些语法可以做到这一点?

编辑 答案是重复的,但我问的是 String.Format 是否可以在 XAML 转换器中使用 Trim Substring 等方法,以及我是否应该重构我的代码,但正确地做它会创建更多代码和复杂性比它消除。

编辑 2 这是代码。基本上列表视图有一个 X 图标和旁边带有文件名的文本,如果用户单击该图标,它将调用:

    private void r1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Rectangle r = sender as Rectangle;
        ticket.removeFilePath(r.DataContext.ToString());
        ticket.fileNames.Remove(r.DataContext.ToString());
    }

使用一个collection,不使用List<T>:

ObservableCollection<String> FilePaths { get; private set; }

如果替换 collection,则需要加注 INotifyPropertyChanged.PropertyChanged

写一个值转换器(好吧,就偷我的):

public class FileName : MarkupExtension, IValueConverter
{
    public override object ProvideValue(IServiceProvider serviceProvider) => this;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return System.IO.Path.GetFileName(value.ToString());
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

并在 DataTemplate 中使用值转换器。由于 FilePathsString 的 collection,因此 DataTemplateDataContext 将是 String,因此绑定不会指定属性 用于绑定。传递给值转换器的值将是字符串本身。

<ListView x:Name="DropList" ItemsSource="{Binding FilePaths}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Label 
                Content="{Binding Converter={local:FileName}}" 
                />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

如果您在这里只处理一个 属性,您可以按照其他答案的建议使用转换器。但是你也可以为你的 Path 对象创建一个新的 Class,并在这个 class 中定义一个 FilePath 字符串 属性 来存储完整路径。 (如果需要,还有更多属性。)

然后你可以只覆盖 Class 中的 ToString 方法到 return 只是 filename.

通过这样做,您不需要更改 XAML,但绑定列表将只显示项目作为由您的覆盖 ToString 方法 return 编辑的结果.

类似于:

public ObservableCollection<MyPath> fileNames { get; set; }


public class MyPath: ObservableObject  //implement INotifyPropertyChanged
{
    private string _filepath;        
    public string FilePath
    {
        get { return _filepath; }
        set
        {
            if (value != _filepath)
            {
                _filepath= value;
                RaisePropertyChanged("FilePath");
            }
        }
    }
    public override string ToString()
    {
        return System.IO.Path.GetFileName(FilePath);
    }
}