среда, 5 октября 2011 г.

Конвертер для получения пути к файлу из пути к папке и имени

Некоторое время назад передо мной возникла простая задача: вывести в текстовом поле полный путь к файлу, при том что в модели он был представлен двумя свойствами: путь к папке с файлом и имя файла. Разделение на два поля в модели было важным с архитектурной точки зрения, заводить дополнительное свойство для их объединения не хотелось. Объединить их требовалось только для отображения пользователю.

Результатом архитектурных изысканий стал конвертер для Multibinding , который позволяет разделить получить путь к файлу из двух составляющих, а также разделить его обратно (для двусторонней привязки).

/// <summary>
/// Конвертирует путь к папке и имя файла в путь к файлу и назад
/// </summary>
public class FolderFilePathConverter : IMultiValueConverter
{

#region IMultiValueConverter Members

/// <summary>
/// Конвертирует путь к папке и имя файла в путь к файлу
/// </summary>
/// <param name="values">
/// values[0] - путь к папке
/// values[1] - имя файла
/// </param>
/// <returns>Путь к файлу</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Contract.IsNotNull(values);
Contract.AreEqual(values.Length, 2);
string[] src = values.Select(x => x == null ? String.Empty : x.ToString()).ToArray();

return System.IO.Path.Combine(src[0], src[1]);

}

/// <summary>
/// Конвертирует путь к файлу в путь к папке и имя файла
/// </summary>
/// <param name="value">Путь к файлу</param>
/// <returns>
/// Массив из 2-х элементов: путь к папке и имя файла
/// </returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "1")]
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
Contract.IsNotNull(targetTypes);
Contract.AreEqual(targetTypes.Length, 2);
return SplitPath(value == null ? string.Empty : value.ToString()).Cast<object>().ToArray();
}

/// <summary>
/// Разбить путь к файлу на путь к папке и имя файла
/// </summary>
private static string[] SplitPath(string value)
{
string[] strings = String.Empty.Repeat(2).ToArray();
if (String.IsNullOrEmpty(value))
return strings;
FileInfo fi = null;
try
{
fi = new FileInfo(value.ToString().RemoveQuotesAndTrim());
}
catch (ArgumentException)
{
return strings;
}
catch (IOException)
{
return strings;
}

strings[0] = fi.DirectoryName;
strings[1] = fi.Name;

return strings;
}

#endregion
}





Использование конвертера выглядит следующим образом:




<TextBox x:Uid="FilePath" IsReadOnly="False" Margin="40,0,0,0" x:Name="FilePath" >
<TextBox.Text>
<MultiBinding Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"
Converter="{StaticResource FolderFilePathConverter}" >
<Binding Path="Folder" />
<Binding Path="FileName" />
</MultiBinding>
</TextBox.Text>
</TextBox>



Комментариев нет:

Отправить комментарий