Conditional mapping of a data template in XAML

I have a list of text blocks that can include urls inside, smth like:

  • Build error, see here: http: // ...
  • Assembly completed
  • App http: // myapp / cannot be started, see more details here: http: // ...

I need to display this (endless) list in a UWP application. Given that this list can be used in several views inside the application, I made it a general template:

<ResourceDictionary>
  <ControlTemplate x:Key="ListItemTemplate" TargetType="ItemsControl">
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <Image Grid.Column="0" Source="{Binding image_url}"/>
      <TextBlock Grid.Column="1" Text="{Binding status}"/>
    </Grid>
  </ControlTemplate>
</ResourceDictionary>

In this template, links are treated as plain text (which is expected). As far as I understand, in order to make links work, I need to wrap them in a tag <HyperLink>, but I can’t do this in the template, because I don’t know where exactly the links will be and how many of them will be displayed.

renderer, (<TextBlock>) , ?

, , , , .

UPD: :

:

<ResourceDictionary xmlns:resources="using:NamespaceWithTextBlockExt">
  <ControlTemplate x:Key="ListItemTemplate" TargetType="ItemsControl">
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <Image Grid.Column="0" Source="{Binding image_url}"/>
      <TextBlock Grid.Column="1" resources:TextBlockExt.XAMLText="{Binding Text}"/>
    </Grid>
  </ControlTemplate>
</ResourceDictionary>

- :

public static class TextBlockExt
{
    public static String GetXAMLText(TextBlock obj)
    {
        return (String)obj.GetValue(XAMLTextProperty);
    }

    public static void SetXAMLText(TextBlock obj, String value)
    {
        obj.SetValue(XAMLTextProperty, value);
    }

    /// <summary>
    /// Convert raw string from ViewModel into formatted text in a TextBlock: 
    /// 
    /// @"This <Bold>is a test <Italic>of the</Italic></Bold> text."
    /// 
    /// Text will be parsed as XAML TextBlock content. 
    /// 
    /// See WPF TextBlock documentation for full formatting. It supports spans and all kinds of things. 
    /// 
    /// </summary>
    public static readonly DependencyProperty XAMLTextProperty =
        DependencyProperty.RegisterAttached("XAMLText", typeof(String), typeof(TextBlockExt),
                                             new PropertyMetadata("", XAMLText_PropertyChanged));

    private static void XAMLText_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is TextBlock)
        {
            var ctl = d as TextBlock;

            try
            {
                //  XAML needs a containing tag with a default namespace. We're parsing 
                //  TextBlock content, so make the parent a TextBlock to keep the schema happy. 
                //  TODO: If you want any content not in the default schema, you're out of luck. 
                var value = e.NewValue;

                var strText = String.Format(@"<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">{0}</TextBlock>", e.NewValue);

                TextBlock parsedContent = Windows.UI.Xaml.Markup.XamlReader.Load(strText) as TextBlock;

                //  The Inlines collection contains the structured XAML content of a TextBlock
                ctl.Inlines.Clear();

                var inlines = parsedContent.Inlines.ToList();
                parsedContent.Inlines.Clear();

                //  UI elements are removed from the source collection when the new parent 
                //  acquires them, so pass in a copy of the collection to iterate over. 
                ctl.Inlines.Concat(inlines);
                inlines.ForEach(x => ctl.Inlines.Add(x));
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(String.Format("Error in Ability.CAPS.WPF.UIExtensions.TextBlock.XAMLText_PropertyChanged: {0}", ex.Message));
                throw;
            }
        }
    }
}

, , . URL- :

"App <Hyperlink NavigateUri=\"http://app/\">myapp</Hyperlink>"

, , <InlineUIContainer>

+4
1

, XAML XamlReader.Load(Stream) . , TextBlock , Hyperlink. WPF UWP; .

: , XAML, XAML URL- XAML Hyperlink . .

. HyperLinksToXAMLConverter:

<TextBlock
    local:XAMLText="{Binding status, Converter={StaticResource HyperLinksToXAML}}"
    />
+1

Source: https://habr.com/ru/post/1665748/


All Articles