2

I'm trying to do a Binding on a Property of my Textblockextension. I'm doing that in a CellTemplate but it always gives me that one Error which says:

Binding is not possible for the Property "SetInteractiveText" of type "TextBlock". Binding can only be done with a DependencyProperty of a DependencyObject

Extension:

public static class TextBlockExtension
{
    private static readonly Regex UrlRegex = new Regex(@"(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'"".,<>?«»“”‘’]))", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(500));


    private static readonly Regex EmailRegex = new Regex(@"(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(500));

    private static readonly Regex PhoneRegex = new Regex(@"\+?[\d\-\(\)\. ]{5,}", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));

    private const string RelativeUriDefaultPrefix = "http://";


    public static readonly DependencyProperty InteractiveTextProperty = DependencyProperty.RegisterAttached("InteractiveText", typeof(string), typeof(TextBlock), new UIPropertyMetadata(null,OnInteractiveTextChanged));

    private static void OnInteractiveTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textBlock = d as TextBlock;
        if (textBlock == null) return;

        // we remove all the inlines
        textBlock.Inlines.Clear();

        // if we have no data, we do not need to go further
        var rawText = e.NewValue as string;
        if (string.IsNullOrEmpty(rawText)) return;


        var lastPosition = 0;
        var matches = new Match[3];
        do
        {
            matches[0] = UrlRegex.Match(rawText, lastPosition);
            matches[1] = EmailRegex.Match(rawText, lastPosition);
            matches[2] = PhoneRegex.Match(rawText, lastPosition);

            var firstMatch = matches.Where(x => x.Success).OrderBy(x => x.Index).FirstOrDefault();
            if (firstMatch == matches[0])
            {
                // the first match is an URL
                CreateRunElement(textBlock, rawText, lastPosition, firstMatch.Index);
                lastPosition = CreateUrlElement(textBlock, firstMatch);
            }
            else if (firstMatch == matches[1])
            {
                // the first match is an email
                CreateRunElement(textBlock, rawText, lastPosition, firstMatch.Index);
            }
            else if (firstMatch == matches[2])
            {
                // the first match is a phonenumber
                CreateRunElement(textBlock, rawText, lastPosition, firstMatch.Index);
            }
            else
            {
                // no match, we add the whole text
                textBlock.Inlines.Add(new Run { Text = rawText.Substring(lastPosition) });
                lastPosition = rawText.Length;
            }
        }
        while (lastPosition < rawText.Length);
    }

    private static void CreateRunElement(TextBlock textBlock, string rawText, int startPosition, int endPosition)
    {
        var fragment = rawText.Substring(startPosition, endPosition - startPosition);
        textBlock.Inlines.Add(new Run { Text = fragment });
    }

    private static int CreateUrlElement(TextBlock textBlock, Match urlMatch)
    {
        Uri targetUri;
        if (Uri.TryCreate(urlMatch.Value, UriKind.RelativeOrAbsolute, out targetUri))
        {
            var link = new Hyperlink();
            link.Inlines.Add(new Run { Text = urlMatch.Value });

            if (targetUri.IsAbsoluteUri)
                link.NavigateUri = targetUri;
            else
                link.NavigateUri = new Uri(RelativeUriDefaultPrefix + targetUri.OriginalString);


            textBlock.Inlines.Add(link);
        }
        else
        {
            textBlock.Inlines.Add(new Run { Text = urlMatch.Value });
        }

        return urlMatch.Index + urlMatch.Length;
    }

    public static string GetInteractiveText(DependencyObject obj)
    {
        return (string)obj.GetValue(InteractiveTextProperty);
    }

    public static void SetInteractiveText(DependencyObject obj, string value)
    {
        obj.SetValue(InteractiveTextProperty, value);
    }
}

And XAML:

 <dxg:TreeListColumn Header="Beschreibung" FieldName="Message" >
      <dxg:TreeListColumn.CellTemplate>
           <DataTemplate>
                <TextBlock  utilities:TextBlockExtension.InteractiveText="{Binding Path=(dxg:RowData.Row)}"/>
           </DataTemplate>
      </dxg:TreeListColumn.CellTemplate>
 </dxg:TreeListColumn>

Hope someone can help me!

SamTh3D3v
  • 9,854
  • 3
  • 31
  • 47
Sokui
  • 53
  • 1
  • 10
  • It says Binding is not possible for the Property "SetInteractiveText" of type "TextBlock". Binding can only be done with a DependencyProperty of a DependencyObject – Sokui Feb 14 '17 at 09:11
  • Change destionation target type of you `AttachedProperty` to `TextBlockExtension`. First: Right now it type of `TextBlock` but `TextBlock` doesn't have such property!! change this ->`typeof(TextBlock)` to `typeof(TextBlockExtension)`. – Shakra Feb 14 '17 at 10:05
  • @Shakra Thanks! That fixed it! – Sokui Feb 14 '17 at 10:24
  • @Shakra Maybe you can write this as an answer so i can close the thread and give you rep? – Sokui Feb 14 '17 at 10:30

1 Answers1

2

The owner type of the attached property (i.e. the third argument to RegisterAttached) must be the class in which the property is declared, not any possible type where the property is applied.

Here it must be TextBlockExtension, not TextBlock:

public static readonly DependencyProperty InteractiveTextProperty =
    DependencyProperty.RegisterAttached(
        "InteractiveText",
        typeof(string),
        typeof(TextBlockExtension), // here
        new PropertyMetadata(null, OnInteractiveTextChanged));
Clemens
  • 123,504
  • 12
  • 155
  • 268
Shakra
  • 501
  • 2
  • 8