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
中使用值转换器。由于 FilePaths
是 String
的 collection,因此 DataTemplate
的 DataContext
将是 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);
}
}
大家好,我是 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
中使用值转换器。由于 FilePaths
是 String
的 collection,因此 DataTemplate
的 DataContext
将是 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);
}
}