Управление изображениями демонстрирует интересное свойство XAML, известное как преобразование . Например, XAML апите для изображений выглядеть следующим образом:
<Image Source="http://lorempixel.com/100/100/people" />
Однако программирование API выглядит так:
class Image {
ImageSource Source { get; set;}
DependencyProperty SourceProperty // etc.
}
Как строка заводится в Ури, а затем превратилась в ImageSource?
Ответ лежит на TypeConverters.
[TypeConverter(typeof(ImageSourceConverter))]
public class ImageSource {}
Когда мы программно создаем привязку к Uri, волшебство выше не имеет места. И результат: изображения не отображаются.
// No picture is shown.
BindingOperations.SetBinding(myImage,
Image.SourceProperty, new Binding("MyUri"));
Точно так же мы не можем сделать это:
// compile time error
myImage.Source = new Uri("http://...")
Вместо этого, правильный путь, чтобы принести преобразователь типа из пользовательского атрибута ImageSource и массировать его в IValueConverter. Вот моя - основная работа выполняется с помощью этой одной линии public object Convert(...)
- все остальное подмости:
namespace Caliburn.Micro
{
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
public class ValueTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var result = TypeDescriptor.GetConverter(targetType).ConvertFrom(value);
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
/// <summary>
/// Binding Image.Source to an Uri typically fails.
/// Calling the following during application bootstrap will set this up properly.
/// ConventionManager.ApplyValueConverter = ValueTypeConverter.ApplyValueConverter;
/// </summary>
/// <param name="binding"></param>
/// <param name="bindableProperty"></param>
/// <param name="info"></param>
public static void ApplyValueConverter(Binding binding, DependencyProperty bindableProperty, PropertyInfo info)
{
if (bindableProperty == UIElement.VisibilityProperty && typeof(bool).IsAssignableFrom(info.PropertyType))
binding.Converter = ConventionManager.BooleanToVisibilityConverter;
else if (bindableProperty == Image.SourceProperty && typeof(Uri).IsAssignableFrom(info.PropertyType))
binding.Converter = new ValueTypeConverter();
else
{
foreach (var item in _Conventions)
{
if (bindableProperty == item.Item1 && item.Item2.IsAssignableFrom(info.PropertyType))
binding.Converter = new ValueTypeConverter();
}
}
}
/// <summary>
/// If there is a TypeConverter that can convert a <paramref name="SourceType"/>
/// to the type on <paramref name="bindableProperty"/>, then this has to
/// be manually registered with Caliburn.Micro as Silverlight is unable to
/// extract sufficient TypeConverter information from a dependency property
/// on its own.
/// </summary>
/// <example>
/// ValueTypeConverter.AddTypeConverter<ImageSource>(Image.SourceProperty);
/// </example>
/// <typeparam name="SourceType"></typeparam>
/// <param name="bindableProperty"></param>
public static void AddTypeConverter<SourceType>(DependencyProperty bindableProperty)
{
_Conventions.Add(Tuple.Create<DependencyProperty, Type>(bindableProperty, typeof(SourceType)));
}
private static IList<Tuple<DependencyProperty, Type>> _Conventions = new List<Tuple<DependencyProperty, Type>>();
}
}
Тогда в загрузчике, мы телеграфировать новый IValueConverter:
protected override void Configure()
{
// ...
ConventionManager.ApplyValueConverter =
ValueTypeConverter.ApplyValueConverter;
}
ли Caliburn не позволяют просто написать ' '? Мне намного легче. –
Clemens
И обратите внимание, что * принуждение * означает что-то другое. То, что вы имеете в виду, называется преобразованием типов. – Clemens
Вы правы по обоим пунктам. Благодарю. Я действительно изучал использование преобразования типов для отображения изображений, которые могут быть заменены пользователем, так как это казалось хорошим способом скрыть большую часть связанной с этим сложности. –