hoetz
hoetz

Reputation: 2388

Silverlight 4 Usercontrol Property fails to receive PropertyChanged From Parent Control

I've set up a simple Silverlight 4 control which is supposed to switch the visibility of two textboxes based on a public property. I add the control to a view and set the databinding of the control's property to a property of the parent view's viewmodel. When a change in the parent viewmodel's property occurs, nothing happens in the usercontrol. Although it's bound, the OnPropertyChanged doesnt seem to interest the bound property of the user control. Below is the code of the user control.

<UserControl x:Class="Controls.EAPPasswordBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" x:Name="_root" >

<Grid x:Name="LayoutRoot" Background="White">
    <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Top">
        <PasswordBox x:Name="pwdBox" />
        <TextBox x:Name="txtBox" />
    </StackPanel>
</Grid>

public partial class EAPPasswordBox : UserControl, INotifyPropertyChanged
{
    public bool ShowText
    {

        get { return (bool)GetValue(ShowTextProperty); }
        set { 

            SetValue(ShowTextProperty, value);
               if (value == true)
               {
                   this.pwdBox.Visibility = System.Windows.Visibility.Collapsed;
                   this.txtBox.Visibility = System.Windows.Visibility.Visible;
               }
               else
               {
                   this.pwdBox.Visibility = System.Windows.Visibility.Collapsed;
                   this.txtBox.Visibility = System.Windows.Visibility.Visible;
               }
        }

    }

    private Visibility _PwdBoxVisibility;

    public Visibility PwdBoxVisibility
    {
        get { return _PwdBoxVisibility; }
        set
        {
            _PwdBoxVisibility = value; NotifyPropertyChanged("PwdBoxVisibility");
        }
    }

    private Visibility _TxtBoxVisibility;

    public Visibility TxtBoxVisibility
    {
        get { return _TxtBoxVisibility; }
        set
        {
            _TxtBoxVisibility = value; NotifyPropertyChanged("TxtBoxVisibility");
        }
    }


    public static readonly DependencyProperty ShowTextProperty =
         DependencyProperty.Register("ShowText", typeof(bool), typeof(EAPPasswordBox),null);

    public EAPPasswordBox()
    {
        InitializeComponent();
    }

    private static void OnShowTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {

    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

}

Here is how I use it in my parent view:

<local:EAPPasswordBox x:Name="pwdBox"
                Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" ShowText="{Binding showPassword, Mode=TwoWay}"></local:EAPPasswordBox>


private bool _showPassword;
    public bool showPassword
    {
        get
        {
            return _showPassword;
        }
        set
        {
            _showPassword = value;
            RaisePropertyChanged("showPassword");
        }
    }

When the "showPassword" in the parent view's viewmodel changes, nothing happens in the user control, and it's driving me crazy :) Any ideas? Thank you.

Upvotes: 0

Views: 1179

Answers (2)

Luc Bos
Luc Bos

Reputation: 1732

Implement what you do in the setter of the property in the OnShowTextPropertyChanged handler. The setter will only be used to initialise the binding.

Upvotes: 0

ibebbs
ibebbs

Reputation: 1993

Updates to bound Dependency Properties don't occur with the normal get/set accessors of the property but behind the scenes. As such the only way to intercept when the value is changed is to provider a DependencyPropertyChangedEventHandler in the PropertyMetadata when you create the Dependency Property.

As follows:


public static readonly DependencyProperty ShowTextProperty =
         DependencyProperty.Register("ShowText", typeof(bool), typeof(EAPPasswordBox), new PropertyMetadata(ShowTextPropertyChanged));

private static void ShowTextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    EAPPasswordBox passwordBox = sender as EAPPasswordBox;

    if (passwordBox != null)
    {
        passwordBox.SetVisibilityOfTextBoxes();
    }
}

Hope it helps.

Upvotes: 1

Related Questions