3

I have a TextBox and I'm trying to bind it to a DependencyProperty. The property is never touched on load or when I type in the TextBox. What am I missing?

XAML

<UserControl:Class="TestBinding.UsernameBox"
        // removed xmlns stuff here for clarity>
    <Grid>
        <TextBox Height="23" Name="usernameTextBox" Text="{Binding Path=Username, ElementName=myWindow, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
    </Grid>
</UserControl>

C#

public partial class UsernameBox : UserControl
{
    public UsernameBox()
    {
        InitializeComponent();
    }

    public string Username
    {
        get
        {
            // Control never reaches here
            return (string)GetValue(UsernameProperty);
        }
        set
        {
            // Control never reaches here
            SetValue(UsernameProperty, value);
        }
    }

    public static readonly DependencyProperty UsernameProperty
        = DependencyProperty.Register("Username", typeof(string), typeof(MainWindow));
}

Edit: I need to implement a DependencyProperty because I am creating my own control.

jamesrom
  • 866
  • 3
  • 10
  • 19
  • 1
    You shouldn't be using a DependencyProperty as the source of your binding! See my answer... – markmnl Apr 18 '13 at 01:28
  • 1
    Oops, I did not make that clear. I am actually creating my own control, so it needs to be a Dependency Property. – jamesrom May 07 '13 at 21:44

2 Answers2

10

You never reach setter because it is CLR wrapper of dependency property, it is declared to be set from external sources, like mainWindow.Username = "myuserName";. When the property is set through binding and you want to see if it changed or not just add the PropertyMetadata to your declaration with PropertyChangedCallback, for example:

public static readonly DependencyProperty UsernameProperty =
            DependencyProperty.Register("Username", typeof(string), typeof(MainWindow), new UIPropertyMetadata(string.Empty, UsernamePropertyChangedCallback));

        private static void UsernamePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Debug.Print("OldValue: {0}", e.OldValue);
            Debug.Print("NewValue: {0}", e.NewValue);
        }

With this code you will see changes of your property in Output Window of VS.

For more info on callbacks please read Dependency Property Callbacks and Validation

Hope this helps.

Eugene Cheverda
  • 8,760
  • 2
  • 33
  • 18
  • 3
    See also the explanation in [XAML Loading and Dependency Properties](http://msdn.microsoft.com/en-us/library/bb613563.aspx), section "Implications for Custom Dependency Properties". – Clemens Dec 06 '12 at 09:08
  • Thanks! I knew I was missing something. – jamesrom Dec 07 '12 at 03:37
  • No ways! you should not use a DependencyProperty as the source of your binding - see my answer. – markmnl Apr 18 '13 at 01:27
4

You shouldn't be using a DependencyProperty here!

Your TextBox's Text property is a DependencyProperty and is the target of your binding. Your Username Property is the source and should not be a DependencyProperty! Rather, it should be a plain old property that raises NotifyPropertyChanged.

All you need is:

private string _username;
public string Username
{
    get
    {
        return _username;
    }
    set
    {
        _username = value;
         NotifyPropertyChanged("Username");
    }
}

(Aside: you only need to use DependencyProperties when you are authoring your own control.)

markmnl
  • 11,116
  • 8
  • 73
  • 109