2

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.

PeterOeClausen
  • 370
  • 3
  • 15
  • 1
    See [How to: Create a Custom Routed Event](https://msdn.microsoft.com/en-us/library/ms752288(v=vs.110).aspx), then raise your custom TextChangedEvent in the PropertyChangedCallback of the Text property (shown in the answer by Eric). – Clemens Feb 10 '17 at 14:27
  • Or declare an ordinary CLR event and fire it in the PropertyChangedCallback. – Clemens Feb 10 '17 at 14:44

3 Answers3

2

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
    }
    
Eric
  • 1,737
  • 1
  • 13
  • 17
0

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.

PeterOeClausen
  • 370
  • 3
  • 15
0

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

Aenye_Cerbin
  • 158
  • 10