РЕДАКТИРОВАТЬ:
Эта строка,
<props:Resources x:Key="Resources"/>
- это неправильный подход к доступу к пространству имен Project.Properties.Resources.Это вызывает неловкие сбои при перекомпиляции.
Гораздо лучше использовать x:Static
для чего-то подобного,
Text="{x:Static props:Resources.SomeText}"
в вашей привязке.Спасибо Бен
Хорошо, вот как я это сделал.Это не идеально, но работает.
Помните, что существует ресурс проекта с именем FormattedText.
cs:
// TextBlock with a bindable InlineCollection property.
// Type is List(Inline) not InlineCollection becuase
// InlineCollection makes the IDE xaml parser complain
// presumably this is caused by an inherited attribute.
public class BindableTextBlock : TextBlock
{
public static readonly DependencyProperty InlineCollectionProperty =
DependencyProperty.Register(
"InlineCollection",
typeof(List<Inline>),
typeof(BindableTextBlock),
new UIPropertyMetadata(OnInlineCollectionChanged));
private static void OnInlineCollectionChanged(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
BinableTextBlock instance = sender as BindableTextBlock;
if (instance != null)
{
List<Inline> newText = e.NewValue as List<Inline>;
if (newText != null)
{
// Clear the underlying Inlines property
instance.Inlines.Clear();
// Add the passed List<Inline> to the real Inlines
instance.Inlines.AddRange(newText.ToList());
}
}
}
public List<Inline> InlineCollection
{
get
{
return (List<Inline>)GetValue(InlineCollectionProperty);
}
set
{
SetValue(InlineCollectionProperty, value);
}
}
}
// Convertor between a string of xaml with implied run elements
// and a generic list of inlines
[ValueConversion(typeof(string), typeof(List<Inline>))]
public class StringInlineCollectionConvertor : IValueConverter
{
public object Convert(object value,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
string text = value as String;
// a surrogate TextBlock to host an InlineCollection
TextBlock results = new TextBlock();
if (!String.IsNullOrEmpty(text))
{
//Arbritary literal acting as a replace token,
//must not exist in the empty xaml definition.
const string Replace = "xxx";
// add a dummy run element and replace it with the text
results.Inlines.Add(new Run(Replace));
string resultsXaml = XamlWriter.Save(results);
string resultsXamlWithText = resultsXaml.Replace(Replace, text);
// deserialise the xaml back into our TextBlock
results = XamlReader.Parse(resultsXamlWithText) as TextBlock;
}
return results.Inlines.ToList<Inline>();
}
// Not clear when this will be called but included for completeness
public object ConvertBack(
object value,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
String results = String.Empty;
InlineCollection inlines = value as InlineCollection;
if (inlines != null)
{
//read the xaml as xml and return the "content"
var reader =
XElement.Parse(XamlWriter.Save(inlines)).CreateReader();
reader.MoveToContent();
results = reader.ReadInnerXml();
}
return results;
}
}
xaml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:props="clr-namespace:Project.Properties"
xmlns:local="clr-namespace:Project">
<Window.Resources>
<props:Resources x:Key="Resources"/>
<local:StringInlineCollectionConvertor x:Key="InlineConvert"/>
</Window.Resources>
<local:BindableTextBlock InlineCollection="
{Binding Source={StaticResource Resources},
Path=FormattedText,
Converter={StaticResource InlineConvert}}"/>
</Window>
Я сделал 2 класса.Подклассифицированный TextBlock с «привязываемым» InlineCollection и IValueConverter для преобразования коллекции из и в String.
Использование InlineCollection непосредственно в качестве типа свойства заставило VS2010 выдать жалобу, хотя код все еще работал нормально.Я изменил на общий список Inlines.Я предполагаю, что есть унаследованный атрибут, сообщающий VS, что InlineCollection не имеет конструктора.
Я попытался сделать свойство InlineCollection объектом BindableTextBlock ContentProperty, но столкнулся с проблемами и не успел.Пожалуйста, не стесняйтесь сделать следующий шаг и рассказать мне об этом.
Я прошу прощения за любые ошибки, но этот код должен быть расшифрован и очищен.
Если есть лучший способ сделать этоКонечно, должно быть, пожалуйста, скажите мне это тожеРазве не было бы хорошо, если бы эта функция была встроена или я что-то пропустил?