Search code examples
wpfdependency-propertiestextblock

How to set a dependency property from InLine event of a textblock?


I'm trying to set the dependency property "WordPad" from within the Inline event of MouseEnter from a CustomTextBlock. But this error results:

An object reference is required for the non-static field, method, or property 'WpfCustomControlLibrary.CustomTextBlock.WordPad.get'

How can I achieve this?

Any help would be most appreciated. Thanks.

Given the following class:

 public class CustomTextBlock : TextBlock
{
      public string InLineText
    {
        get { return (string)GetValue(InLineTextProperty); }
        set { SetValue(InLineTextProperty, value); }
    }

     public static readonly DependencyProperty InLineTextProperty =
        DependencyProperty.Register("InLineText", typeof(string), typeof(CustomTextBlock),
            new FrameworkPropertyMetadata(string.Empty,
                FrameworkPropertyMetadataOptions.AffectsMeasure,
                (o, e) =>
                {
                    //PropertyChangedCallback

                    CustomTextBlock tb = (CustomTextBlock)o;
                    string text = (string)e.NewValue;

                    tb.Inlines.Clear();

                    if (String.IsNullOrEmpty(text))
                        return;

                    List<Inline> inlines = new List<Inline>();

                    string[] words = Regex.Split(text, @"(\s+)");

                    Inline inline = null;
                    foreach (string s in words)
                    {
                        Run run = new Run(s);
                        inline = run;
                        inline.MouseEnter += new System.Windows.Input.MouseEventHandler(inline_MouseEnter);
                        inline.MouseLeave += new System.Windows.Input.MouseEventHandler(inline_MouseLeave);
                        tb.Inlines.Add(inline);
                    }
                }));


     public WritingPad WordPad
    {
        get { return (WritingPad)GetValue(WordPadProperty); }
        set { SetValue(WordPadProperty, value); }
    }

     public static readonly DependencyProperty WordPadProperty =
        DependencyProperty.Register("WordPad", typeof(WritingPad), typeof(CustomTextBlock), new UIPropertyMetadata(null));


static void inline_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
    {
        Run Sender = sender as Run;
        TextPointer tp0 = Sender.ContentStart;
        TextPointer tp1 = Sender.ContentEnd;

        Rect StartRect = tp0.GetCharacterRect(LogicalDirection.Forward);
        Rect EndRect = tp1.GetCharacterRect(LogicalDirection.Backward);
        StartRect.Union(EndRect);

        WordPad = new WritingPad();   <--**THIS FAILS ????


    }

Solution

  • Make the inline_MouseEnter and inline_MouseLeave methods non-static and attach them to your Runs like this:

    inline.MouseEnter += tb.inline_MouseEnter;
    inline.MouseLeave += tb.inline_MouseLeave;
    

    Even better would be to make the whole PropertyChangedCallback non-static and then write the dependency property declaration like this:

    public static readonly DependencyProperty InLineTextProperty =
        DependencyProperty.Register("InLineText", typeof(string), typeof(CustomTextBlock),
            new FrameworkPropertyMetadata(string.Empty,
                FrameworkPropertyMetadataOptions.AffectsMeasure,
                (o, e) => ((CustomTextBlock)o).InlineTextChanged((string)e.NewValue)));
    
    private void InlineTextChanged(string text)
    {
        Inlines.Clear();
    
        if (!string.IsNullOrEmpty(text))
        {
            foreach (string s in Regex.Split(text, @"(\s+)"))
            {
                var run = new Run(s);
                run.MouseEnter += inline_MouseEnter;
                run.MouseLeave += inline_MouseLeave;
                Inlines.Add(run);
            }
        }
    }