How to add properties to WPF components?

Asked

Viewed 192 times

2

I can use as an example the System.Windows.Controls.TextBox. How do I add more behaviors and properties to it?

In a real context, I would like the component TextBox had a boolean property HasErrors, that if it were true, it would leave the component in red until such error was corrected. I know there are ways to do this with Triggers, changing the Background, but would like to customize the component itself.

How to customize with WPF component? The closest way to do this would be to just create a new component that you inherit from TextBox, how do I do that?

1 answer

3


If you want to have a Textbox with a new property, the way is to inherit from Textbox and add the new property as a Dependencyproperty.

Example where the Haserrors property is added that when true puts Background in red.

public class HasErrorsTextBox : TextBox
{
    private Brush NoErrorsBackgroundColor { get; set; }

    public static readonly DependencyProperty HasErrorsProperty = DependencyProperty.Register(
          "HasErrors",
          typeof(bool),
          typeof(HasErrorsTextBox),
          new FrameworkPropertyMetadata(false, OnHasErrorsChanged)
        );

    public bool HasErrors
    {
        get { return (bool)GetValue(HasErrorsProperty); }
        set { SetValue(HasErrorsProperty, value); }
    }


    private static void OnHasErrorsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textBox = d as HasErrorsTextBox;
        if (textBox.NoErrorsBackgroundColor == null)
        {
            textBox.NoErrorsBackgroundColor = textBox.Background;
        }

        textBox.Background = (bool)e.NewValue ? Brushes.Red : textBox.NoErrorsBackgroundColor;
    }

}

Way to use:

<local:HasErrorsTextBox Text="HasErrorsTextBox" HasErrors="True"/>

Another approach is to create a Attached Property. This approach allows you to create a property that can be associated(Attached) to the same group of components.
In this example, it could be applied to any component that has the Background property (any type it inherits from Control).

Example implementing a Attached Property:

public static class MyAttachedProperties
{
    private static Brush NoErrorsBackgroundColor { get; set; }

    public static readonly DependencyProperty HasErrorsProperty = DependencyProperty.RegisterAttached(
          "HasErrors",
          typeof(bool),
          typeof(MyAttachedProperties),
          new FrameworkPropertyMetadata(false, OnHasErrorsChanged)
        );

    public static bool GetHasErrors(DependencyObject d)
    {
        return (bool)d.GetValue(HasErrorsProperty);
    }

    public static void SetHasErrors(DependencyObject d, bool value)
    {
        d.SetValue(HasErrorsProperty, value);
    }

    private static void OnHasErrorsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = d as Control;
        if (control == null)
        {
            throw new
                InvalidOperationException("Esta propriedade apenas pode ser aplicada a objectos do tipo Control");
        }

        if (NoErrorsBackgroundColor == null)
        {
            NoErrorsBackgroundColor = control.Background;
        }

        control.Background = (bool)e.NewValue ? Brushes.Red : NoErrorsBackgroundColor;

    }

}

Way to use:

<TextBox Text="AttachedProperty" local:MyAttachedProperties.HasErrors="True"/>
  • Got it! With inheritance, can you add something to the UI? Like adding a magnifying glass (path or image) to the Textbox.

  • In this case maybe the best is a User Control.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.