Hey team,
We've previously had them as glyphs in the font. However, I'm trying to implement this using sfernandez's approach with inline images. We have them stored in a control template at the moment, so I've written some code to put them in a Content Control.
I was able to get it parsing the text and displaying the image correctly in Blend using C# with the following code:
namespace Extensions
{
// Source: https://stackoverflow.com/questions/14058814/format-part-of-the-text-of-textblock-using-ivalueconverter
public class paTextBlockTooltipEx
{
public static Inline GetFormattedText(DependencyObject obj)
{
return (Inline)obj.GetValue(FormattedTextProperty);
}
public static void SetFormattedText(DependencyObject obj, Inline value)
{
obj.SetValue(FormattedTextProperty, value);
}
public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
"FormattedText",
typeof(Inline),
typeof(paTextBlockTooltipEx),
new PropertyMetadata(null, OnFormattedTextChanged)
);
private static void OnFormattedTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (!(o is TextBlock textBlock))
{
return;
}
InlineCollection inlines = textBlock.Inlines;
inlines.Clear();
Inline newInlineValue = (Inline)e.NewValue;
if (newInlineValue != null)
{
inlines.Add(newInlineValue);
}
}
}
public class InlineInputTypeConverter : IValueConverter
{
private static readonly Dictionary<string, TooltipsVM.InputType> SymbolsPaths = new Dictionary<string, TooltipsVM.InputType> {
{ "CROSS", TooltipsVM.InputType.Cross},
};
public TooltipConverter TooltipConverterProp { get; private set; }
public InlineInputTypeConverter()
{
TooltipConverterProp = new TooltipConverter();
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string valueStr = value != null ? (string)value : (string)parameter;
string[] splitStrings = valueStr.Split('|');
Span textBlock = new Span();
InlineCollection inlines = textBlock.Inlines;
foreach(string splitStr in splitStrings)
{
if (SymbolsPaths.ContainsKey(splitStr))
{
var content = new ContentControl();
content.Template = (ControlTemplate)TooltipConverterProp.ConvertInputType(SymbolsPaths[splitStr]);
var viewbox = new Viewbox();
viewbox.Child = content;
viewbox.MaxHeight = 60;
inlines.Add(new InlineUIContainer(viewbox));
}
else
{
inlines.Add(new Run(splitStr));
}
}
return textBlock;
}
}
}
<TextBlock
Foreground="Black"
paEx:paTextBlockTooltipEx.FormattedText="{Binding ConverterParameter='Cross = |CROSS|',
Converter={StaticResource inlineInputTypeConverter}}"
/>
However, I'm struggling to convert this to C++. I don't know what paTextBlockTooltipEx's base class should be. I thought it may need need to be a Noesis::MarkupExtension but I couldn't find any sample code to point me in the right direction.
This is what I have so far:
class paTextBlockTooltipEx : public Noesis::MarkupExtension
{
public:
static const Noesis::Inline& GetFormattedText(const Noesis::DependencyObject& obj);
static void SetFormattedText(Noesis::DependencyObject* obj, const Noesis::Inline& value);
static const Noesis::DependencyProperty* m_FormattedTextProperty;
virtual Noesis::Ptr<Noesis::BaseComponent> ProvideValue(const Noesis::ValueTargetProvider* provider) override { return nullptr; };
NS_DECLARE_REFLECTION(paTextBlockTooltipEx, Noesis::MarkupExtension)
LUA_BIND_CLASS_HEADER();
private:
static void OnFormattedTextChanged(Noesis::DependencyObject*, const Noesis::DependencyPropertyChangedEventArgs& e);
};
const Noesis::Inline& paTextBlockTooltipEx::GetFormattedText(const Noesis::DependencyObject& obj)
{
return obj.GetValue<Noesis::Inline>(m_FormattedTextProperty);
}
void paTextBlockTooltipEx::SetFormattedText(Noesis::DependencyObject* obj, const Noesis::Inline& value)
{
obj->SetValue<Noesis::Inline>(m_FormattedTextProperty, value);
}
void paTextBlockTooltipEx::OnFormattedTextChanged(Noesis::DependencyObject* obj, const Noesis::DependencyPropertyChangedEventArgs& e)
{
auto textBlock = (Noesis::TextBlock*)obj;
if (!textBlock)
{
return;
}
auto inlines = textBlock->GetInlines();
if (!inlines)
{
return;
}
inlines->Clear();
const auto newInlineValue = (Noesis::Inline*)e.newValue;
if (!newInlineValue)
{
return;
}
inlines->Add(newInlineValue);
}
NS_BEGIN_COLD_REGION
NS_IMPLEMENT_REFLECTION(paTextBlockTooltipEx)
{
NsMeta("FormattedText", &paTextBlockTooltipEx::m_FormattedTextProperty);
}
Any ideas?
Thanks,
R