9

I have a custom text box defined as follows:

public class CustomTextBox : TextBox
{
    public static DependencyProperty CustomTextProperty = 
             DependencyProperty.Register("CustomText", typeof(string), 
             typeof(CustomTextBox));

    static CustomTextBox()
    {
        TextProperty.OverrideMetadata(typeof(SMSTextBox),
                      new FrameworkPropertyMetadata(string.Empty,
                      FrameworkPropertyMetadataOptions.Journal |
                          FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                      new PropertyChangedCallback(CustomTextBox_OnTextPropertyChanged));
    }

    public string CustomText
    {
        get { return (string)GetValue(CustomTextProperty); }
        set { SetValue(CustomTextProperty, value); }
    }

    private static void CustomTextBox_OnTextPropertyChanged(DependencyObject d,
                     DependencyPropertyChangedEventArgs e)
    {
        CustomTextBox customTextBox = d as CustomTextBox;

        customTextBox.SetValue(CustomTextProperty, e.NewValue);
    }
}

I'm binding the Custom Text property in the XAML -

<local:CustomTextBox CustomText="{Binding ViewModelProperty}" />

The problem I'm facing is that when I enter anything in the CustomTextBox, the changes are not reflected in the ViewModelProperty i.e. the ViewModelProperty is not getting updated. The CustomTextProperty is getting updated but I suppose I need to do something extra to make the binding work as well.

What am I not doing? I would appreciate any help regarding this.

Thank you

Cool Blue
  • 6,438
  • 6
  • 29
  • 68
Duke Cyrillus
  • 1,217
  • 2
  • 14
  • 29
  • What are you trying to accomplish with the PropertyChanged callback? To me it looks like you just set a new value, thats why this callback was called, it again which luckly is catched by wpf otherwise you would have a endless loop. – dowhilefor Jan 31 '13 at 14:57

1 Answers1

8

I guess the binding needs to be two-way.

<local:CustomTextBox
    CustomText="{Binding ViewModelProperty, Mode=TwoWay}" />

You wouldn't need to specify the Mode if you made the CustomText property bind two-way by default:

public static readonly DependencyProperty CustomTextProperty =
    DependencyProperty.Register(
        "CustomText", typeof(string), typeof(CustomTextBox),
        new FrameworkPropertyMetadata(
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

You may also have to define a PropertyChangedCallback for the CustomText property that updates the Text property (i.e. the other direction of what you have implemented now). Otherwise the TextBox won't display anything that is initially contained in the ViewModel property and of course woudln't be updated when the ViewModel property changes.

Clemens
  • 123,504
  • 12
  • 155
  • 268
  • Thanks!! That worked. However, when I do not enter anything in the textbox and try to refresh the page (I think it refreshes the UC but I'm not really sure), I get an exception like this: Key cannot be null. Parameter name: key – Duke Cyrillus Jan 31 '13 at 15:19
  • Doesn't sound like something that has to do with this property or the binding. What exactly means "refreshing the page"? – Clemens Jan 31 '13 at 15:31
  • 1
    There's a button that performs a validation on all fields (this is done using IDataErrorInfo and re-assigning each property its value). When I click this button, it goes through the validations without any issues but once they're done, the application throws the above mentioned exception. I tried removing the binding (and using the TextBox's Text property) and it worked just fine. When I bind the CustomText/Text property, I get the exception, which is why I assume it's the binding that's causing issues. – Duke Cyrillus Jan 31 '13 at 15:35
  • Still hard to tell what exactly the parameter named "key" is, which is null. Is it perhaps your `ViewModelProperty` that can't be null? Maybe you need to specify `string.Empty` as default value for your `CustomText` property. – Clemens Jan 31 '13 at 15:45
  • The ViewModelProperty can be null - it's an invalid value but it's supposed to be handled during the validations which is working, i.e. the error message is being assigned correctly for that scenario. I did specify a default value for CustomText as well just in case, but it's still not working. The stack trace for the exception didn't help me much either since it didn't point to anything in my code – Duke Cyrillus Jan 31 '13 at 15:50