Это отлично работает, если присутствует только 1 гиперссылка, но возникает проблема, отображается более одной гиперссылки, и возникла проблема ниже
--------- Трассировка стека ---- ----- в System.String.Substring (System.Int32 startIndex, длина System.Int32) [0x0004c] в: 0 в MPI.UI.Mobile.Converter.HtmlLabelConverter.ProcessString (System.String rawText) [0x0004b] в : 0 в MPI.UI.Mobile.Converter.HtmlLabelConverter.Convert (значение System.Object, System.Type targetType, параметр System.Object, язык System.Globalization.CultureInfo) [0x00008] в: 0 в Xamarin.Forms.Binding. GetSourceValue (значение System.Object, System.Type targetPropertyType) [0x0001b] в <036ea626158e48a4b8dcc52d0593c6a6>: 0 в Xamarin.Forms.BindingExpression.ApplyCore (System.Object sourceObject, Xamarin.ProcessObormable, System.Object sourceObject, Xamarin. .Boolean fromTarget) [0x001ce] в <036ea626158e48a4b8dcc52d0593c6a6>: 0 в Xamarin.Forms.BindingExpression.Apply (System.Boolean fromTarget) [0 x0003e] в <036ea626158e48a4b8dcc52d0593c6a6>: 0 в Xamarin.Forms.BindingExpression + BindingExpressionPart.b__49_0 () [0x00000] в <036ea626158e48a4b8dcc52.d0593c6a20]: * [Run]. Java .Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00009] in: 0 в (динамическая оболочка c -method) System.Object.18 (intptr, intptr) ---- --------------------------- --------- Сообщение --------- Индекс и длина должны ссылка на место в строке. Имя параметра: длина ------------------------------- --------- Источник ----- ---- mscorlib ------------------------------- </p>
HtmlLabelConverter
Добавьте следующий HtmlLabelConverter. Это поддерживает несколько ссылок в теле текста, но не любые другие элементы HTML.
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;
}
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)
{
*****sections.Add(new StringSection() { Text = rawText.Substring(lastIndex, item.Index) });***** <!--Here the issue occurs -->
*****lastIndex += item.Index + item.Length;***** <!--Here the issue occurs -->
// 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) });*** <!--Here the issue occurs -->
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));
});
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Затем XAML, я бы назвал его так.
<ContentPage.Resources>
<ResourceDictionary>
<local:HtmlLabelConverter x:Key="HtmlLabelConverter" />
</ResourceDictionary>