Pregunta

Tengo un TextBlock unido a una propiedad. Sin embargo, me gustaría negrilla ciertas palabras dentro del texto. ¿Cuál es la manera más fácil de hacer esto? Para su información, soy nuevo en WPF.

¿Fue útil?

Solución

Bolding palabras individuales en realidad implica la creación de más elementos en línea, por lo que no sólo puede unirse a una cadena de texto del TextBlock y hacer esto.

Lo que he hecho para esto en el pasado se crea una subclase de TextBlock que tiene una propiedad personalizada que se unen a. Cuando esta propiedad está obligado puedo borrar los inlines de TextBlock base y luego usar un algoritmo que analiza el nuevo valor de cadena o bien la creación de Carreras de fricción, Bolds, hipervínculos, etc.

A continuación, algunos ejemplos de código que escribí para mi cliente experimental Twitter que detecta URLs, correos electrónicos y patrón @ y crea hipervínculos para ellos. texto normal se colocarán en línea como carreras normales:

[ContentProperty("StatusText")]
public sealed class StatusTextBlock : TextBlock
{
    #region Fields

    public static readonly DependencyProperty StatusTextProperty = DependencyProperty.Register(
                                                                                    "StatusText", 
                                                                                          typeof(string),
                                                                                    typeof(StatusTextBlock),
                                                                                    new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.None, StatusTextBlock.StatusTextPropertyChangedCallback, null));
    private static readonly Regex UriMatchingRegex = new Regex(@"(?<url>[a-zA-Z]+:\/\/[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,5}(:[0-9]{1,5})?([a-zA-Z0-9_\-\.\~\%\+\?\=\&\;\|/]*)?)|(?<emailAddress>[^\s]+@[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,5})|(?<toTwitterScreenName>\@[a-zA-Z0-9\-_]+)", RegexOptions.Compiled);

    #endregion

    #region Constructors

    public StatusTextBlock()
    {
    }

    #endregion

    #region Type specific properties

    public string StatusText
    {
        get
        {
            return (string)this.GetValue(StatusTextBlock.StatusTextProperty);
        }

        set
        {
            this.SetValue(StatusTextBlock.StatusTextProperty, value);
        }
    }

    #endregion

    #region Helper methods

    internal static IEnumerable<Inline> GenerateInlinesFromRawEntryText(string entryText)
    {
        int startIndex = 0;
        Match match = StatusTextBlock.UriMatchingRegex.Match(entryText);

        while(match.Success)
        {
            if(startIndex != match.Index)
            {
                yield return new Run(StatusTextBlock.DecodeStatusEntryText(entryText.Substring(startIndex, match.Index - startIndex)));
            }

            Hyperlink hyperLink = new Hyperlink(new Run(match.Value));

            string uri = match.Value;

            if(match.Groups["emailAddress"].Success)
            {
                uri = "mailto:" + uri;
            }
            else if(match.Groups["toTwitterScreenName"].Success)
            {
                uri = "http://twitter.com/" + uri.Substring(1);
            }

            hyperLink.NavigateUri = new Uri(uri);

            yield return hyperLink;

            startIndex = match.Index + match.Length;

            match = match.NextMatch();
        }

        if(startIndex != entryText.Length)
        {
            yield return new Run(StatusTextBlock.DecodeStatusEntryText(entryText.Substring(startIndex)));
        }
    }

    internal static string DecodeStatusEntryText(string text)
    {
        return text.Replace("&gt;", ">").Replace("&lt;", "<");
    }

    private static void StatusTextPropertyChangedCallback(DependencyObject target, DependencyPropertyChangedEventArgs eventArgs)
    {
        StatusTextBlock targetStatusEntryTextBlock = (StatusTextBlock)target;

        targetStatusEntryTextBlock.Inlines.Clear();

        string newValue = eventArgs.NewValue as string;

        if(newValue != null)
        {
            targetStatusEntryTextBlock.Inlines.AddRange(StatusTextBlock.GenerateInlinesFromRawEntryText(newValue));
        }
    }

    #endregion
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top