KevinA
KevinA

Reputation: 629

TwoWay DataBinding in a UserControl

I have a UserControl. It Contains a single textbox with an Adorner (removed for brevity)

<UserControl x:Class="Test.UserControlBindings"         
         DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"
         mc:Ignorable="d" KeyboardNavigation.TabNavigation="Cycle" x:Name="Control"
         d:DesignHeight="300" d:DesignWidth="300"  >
    <AdornerDecorator>
        <TextBox x:Name="InputTextBox" VerticalContentAlignment="Center" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="{Binding ElementName=Control, Path=FontSize}"/>
    </AdornerDecorator>
</UserControl>

I'm binding it to "Text" of the UserControl

public partial class WatermarkTextBox : INotifyPropertyChanged {
    private static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(WatermarkTextBox), new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

    public WatermarkTextBox() {
        this.InitializeComponent();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public string Text {
        get {
            return (string)GetValue(TextProperty);
        }

        set {
            this.SetValue(TextProperty, value);
            OnPropertyChanged("Text");
        }
    }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName = null) {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

The Setter is never being called. So when I bind to this user control, the bindings are never updated. What can I do to fix the binding?

Upvotes: 0

Views: 56

Answers (1)

wilford
wilford

Reputation: 51

Bindings don't use the getters and setters, they use GetValue and SetValue directly. You also don't need to implement INotifyPropertyChanged. In order to specify a change handler, include it in your metadata definition like this:

public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
    "Text", typeof(string), typeof(WatermarkTextBox),
    new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
        (s, e) => ((WatermarkTextBox)s).OnTextChanged((string)e.OldValue, (string)e.NewValue))
);

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

void OnTextChanged(string oldValue, string newValue) { 
    //....
}

Upvotes: 1

Related Questions