TextChanged or ContentChanged event in a custom control extending UserControl WPF

1.7k Views Asked by At

I have a custom control in an open source application that I want to change.

The XAML looks like this:

<controls:Scratchpad Grid.Row="1" Grid.Column="2"
                         Text="{Binding DataContext.KeyboardOutputService.Text, RelativeSource={RelativeSource AncestorType=controls:KeyboardHost}, Mode=OneWay}"/>

The codebehind for the Scratchpad control looks like this:

public class Scratchpad : UserControl
{
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof (string), typeof (Scratchpad), new PropertyMetadata(default(string)));

    public string Text
    {
        get { return (string) GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
}

I want to trigger an event handler each time the text changes in the UserControl. However there is no TextChanged event that I can use in the XAML.

My plan was to do something like this:

<controls:Scratchpad Grid.Row="1" Grid.Column="2"
                         Text="{Binding DataContext.KeyboardOutputService.Text, RelativeSource={RelativeSource AncestorType=controls:KeyboardHost}, Mode=OneWay}"
                         textChanged="EventHandler"/>

However the "textChanged" event does not exist in this custom control.

As you can see, ScratchPad extends UserControl. UserControl also extends ContentControl, and that's why I think it is possible to put text in this control, their might be a "ContentChanged" event that I don't know about.

Best, Peter.

3

There are 3 best solutions below

0
On BEST ANSWER

Two options:

  1. (MVVM way) If the change is to reflect something in the domain model, perhaps this change is best suited for handling in your viewmodel

  2. (Control way) Have you considered putting a changed handler in your DependencyProperty?

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(ScratchPad), new PropertyMetadata(null, OnTextChanged));
    
    private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Handle change here
    }
    
0
On

In your custom control you can add:

public event EventHandler? ValueChanged;

And in parent control add the value to this handler (should even be visible in Designer). Add in xaml file of parent:

ValueChanged="name_ValueChanged"

And in associated cs file:

private void name_ValueChanged(object sender, EventArgs e) {
            //Your logic here
}

And you should be able to see it in Designer:

enter image description here

0
On

Thanks a lot for your answer Eric.

I ended up putting in an extra line of code in the Setter of the "KeyboardOutputService.Text". However if I were to add an OnTextChanged eventhandler I would try your approach. I might run into the same problem later, so I'll keep this thread up.

Thanks a lot.