【问题标题】:Hyperlinks not rendering Xamarin.forms超链接不呈现 Xamarin.forms
【发布时间】:2020-04-21 16:02:39
【问题描述】:

我创建了一个类,它试图从一组标签中解析超链接,它似乎可以识别超链接,但不会将标签中的正确跨度更改为超链接。 我第一次尝试:

public class HtmlLabelConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var formatted = new FormattedString();

            foreach (var item in ProcessString((string)value))
                formatted.Spans.Add(CreateSpan(item));

            return formatted;
        }

        private Span CreateSpan(StringSection section)
        {
            var span = new Span()
            {
                Text = section.Text
            };

            if (!string.IsNullOrEmpty(section.Link))
            {
                span.GestureRecognizers.Add(new TapGestureRecognizer()
                {
                    Command = _navigationCommand,
                    CommandParameter = section.Link
                });
                span.TextColor = Color.Blue;
                span.TextDecorations = TextDecorations.Underline;
            }

            return span;
        }

        public IList<StringSection> ProcessString(string rawText)
        {
            const string spanPattern = @"(<a.*?>.*?</a>)";

            MatchCollection collection = Regex.Matches(rawText, spanPattern, RegexOptions.Singleline);

            var sections = new List<StringSection>();

            var lastIndex = 0;

            foreach (Match item in collection)
            {
                var foundText = item.Value;
                sections.Add(new StringSection() { Text = rawText.Substring(lastIndex, item.Index) });
                lastIndex += item.Index + item.Length;

                // Get HTML href 
                var html = new StringSection()
                {
                    Link = Regex.Match(item.Value, "(?<=href=\\\")[\\S]+(?=\\\")").Value,
                    Text = Regex.Replace(item.Value, "<.*?>", string.Empty)
                };

                sections.Add(html);
            }

            sections.Add(new StringSection() { Text = rawText.Substring(lastIndex) });

            return sections;
        }

        public class StringSection
        {
            public string Text { get; set; }
            public string Link { get; set; }
        }

        private ICommand _navigationCommand = new Command<string>((url) =>
        {
            //Device.OpenUri(new Uri(url));
            Launcher.TryOpenAsync(new Uri(url));
        });

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

与 xaml 中的<Label x:Name="labelParagraph" FormattedText="{Binding Paragraph, Converter={StaticResource HtmlLabelConverter}}"/> 和格式如下&lt;a href="www.google.com"&gt; link &lt;/a&gt; 的文本,它从文本中删除&lt;a href&gt; 部分,但不会将link 转换为超链接。这告诉我它正在查找超链接,但由于某种原因没有执行该命令。 其次,我尝试了以下自定义标签:

public class LinksLabel : Label
    {
        public static BindableProperty LinksTextProperty = BindableProperty.Create(nameof(LinksText), typeof(string), typeof(LinksLabel), propertyChanged: OnLinksTextPropertyChanged);

        private readonly ICommand _linkTapGesture = new Command<string>((url) => Device.OpenUri(new Uri(url)));

        public string LinksText
        {
            get => GetValue(LinksTextProperty) as string;
            set => SetValue(LinksTextProperty, value);
        }

        private void SetFormattedText()
        {
            var formattedString = new FormattedString();

            if (!string.IsNullOrEmpty(LinksText))
            {
                var splitText = LinksText.Split(' ');

                foreach (string textPart in splitText)
                {
                    var span = new Span { Text = $"{textPart} " };

                    if (IsUrl(textPart)) // a link
                    {
                        span.TextColor = Color.DeepSkyBlue;
                        span.GestureRecognizers.Add(new TapGestureRecognizer
                        {
                            Command = _linkTapGesture,
                            CommandParameter = textPart
                        });
                    }

                    formattedString.Spans.Add(span);
                }
            }

            this.FormattedText = formattedString;
        }

        private bool IsUrl(string input)
        {
            return Uri.TryCreate(input, UriKind.Absolute, out var uriResult) &&
              (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
        }

        private static void OnLinksTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var linksLabel = bindable as LinksLabel;
            linksLabel.SetFormattedText();
        }
    }

<custom:LinksLabel LinksText="blah blah blah www.google.com blah"/> 但这同样不会向超链接呈现任何内容。

【问题讨论】:

  • 您是否在调试器中逐步完成了此操作?
  • 第一个解决方案对我有用。你一定错过了什么。
  • 第一个解决方案是直接从我的代码中复制的,所以一定有什么东西阻止它在其他地方工作

标签: c# xamarin xamarin.forms xamarin-studio


【解决方案1】:

试试这个解决方案,它会给你超链接的外观和感觉。

XAML:

<Label HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand">
    <Label.FormattedText>
        <FormattedString>
            <Span Text="Hello " />
            <Span Text="Click Me!"
                  TextColor="Blue"
                  TextDecorations="Underline">
                <Span.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding ClickCommand}"
                                          CommandParameter="https://xamarin.com" />
                </Span.GestureRecognizers>
            </Span>
            <Span Text=" Some more text." />
        </FormattedString>
    </Label.FormattedText>
</Label>

如果您使用 ViewModel 创建命令或使用点击手势

public ICommand ClickCommand => new Command<string>((url) =>
{
    Device.OpenUri(new System.Uri(url));
});

【讨论】:

  • 我不确定这是否可行,因为我需要它来遍历段落并找到超链接
【解决方案2】:

事实证明,我在 xaml.cs 中创建并添加了一个额外的滚动布局,以便页面可滚动,但它阻止了底层堆栈布局中的任何可点击内容。我将&lt;ScrollView&gt; 移到了 xaml 文件中,它起作用了。

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 2021-08-31
    • 2011-02-27
    • 1970-01-01
    相关资源
    最近更新 更多