Событие TextChanged или ContentChanged в пользовательском элементе управления, расширяющее пользовательский контроль WPF

У меня есть пользовательский элемент управления в приложении с открытым исходным кодом, который я хочу изменить.

XAML выглядит так:

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

Код для элемента управления Scratchpad выглядит следующим образом:

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); }
    }
}

Я хочу запускать обработчик событий каждый раз, когда текст изменяется в UserControl. Однако в XAML я не могу использовать событие TextChanged.

Мой план состоял в том, чтобы сделать что-то вроде этого:

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

Однако событие textChanged не существует в этом пользовательском элементе управления.

Как видите, ScratchPad расширяет UserControl. UserControl также расширяет ContentControl, и поэтому я думаю, что возможно поместить текст в этот элемент управления, это может быть событие "ContentChanged", о котором я не знаю.

Лучше всего, Питер.

3 ответа

Решение

Два варианта:

  1. (Путь MVVM) Если изменение должно отражать что-то в модели предметной области, возможно, это изменение лучше всего подходит для обработки в вашей модели представления

  2. (Контроль способа) Рассматривали ли вы вопрос об изменении измененного обработчика в свой 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
    }
    

В свой пользовательский элемент управления вы можете добавить:

      public event EventHandler? ValueChanged;

И в родительском контроле добавьте значение этому обработчику (должно быть видно даже в Дизайнере). Добавьте в xaml-файл родителя:

      ValueChanged="name_ValueChanged"

И в связанном файле cs:

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

И вы должны увидеть это в Designer:

Большое спасибо за ваш ответ, Эрик.

Я закончил тем, что добавил дополнительную строку кода в Setter "KeyboardOutputService.Text". Однако, если бы я добавил обработчик события OnTextChanged, я бы попробовал ваш подход. Я мог бы столкнуться с той же проблемой позже, поэтому я буду продолжать эту тему.

Большое спасибо.

Другие вопросы по тегам