1

I have followed the example in this post: Dependency Property is not updating my Usercontrol and have downloaded the example from here: http://www.mediafire.com/file/y1qvv6b68tjibh1/DependencyPropertyInsideUserControl.zip/file

What I want to do is to add a new Property onto the UserControl that has its value set from the already existing Property CellValue.

So the usercontrol is like so:

<UserControl x:Class="DependencyPropertyInsideUserControl.control"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid Height="Auto" Width="Auto">
    <Grid.RowDefinitions>
        <RowDefinition Height="35"/>
        <RowDefinition Height="35" />
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" Text="{Binding Path = CellValue}" Name="textBox2" />
    <TextBox Grid.Row="1" Text="{Binding Path = MyNewValue}" Name="myNewTextBox" />  <-- I have added this in
</Grid>

Now I want MyNewValue to get updated automatically whenever the user updates CellValue. So I have done the following in the code behind:

Added in the following:

    public string MyNewValue
    {
        get { return (string)GetValue(MyNewValueProperty); }
        set { SetValue(MyNewValueProperty, value); }
    }

    public static readonly DependencyProperty MyNewValueProperty =
             DependencyProperty.Register("MyNewValue", typeof(string), typeof(control), new FrameworkPropertyMetadata
             {
                 BindsTwoWayByDefault = true,
             });

And added in a second call to SetValue(MyNewValueProperty, value) in the handler for CellValue:

    public string CellValue
    {
        get
        {
            return (string)GetValue(CellValueProperty);
        }
        set
        {
            SetValue(CellValueProperty, value);                
            SetValue(MyNewValueProperty, value);    <-- Update  MyNewValueProperty whenever CellValueProperty gets updated
        }

    }

But it does not work, MyNewValue never changes whenever CellValue changes. I only want the user to change one value which is CellValue How can I have one property in the UserControl change when another one is modified?

Harry Boy
  • 4,159
  • 17
  • 71
  • 122

1 Answers1

0

What you're missing is the difference between the "CLR 'wrapper'" and the underlying DependencyProperty. You can read up on them here: Dependency properties overview. I'll draw your attention to one particular quote:

Setting properties in code

Setting dependency property values in code is typically just a call to the set implementation exposed by the CLR "wrapper". Getting a property value is also essentially a call to the get "wrapper" implementation. You can also call the property system APIs GetValue and SetValue directly.

That is what the WPF framework is doing internally when a binding needs to update a dependency property. It doesn't call the "CLR 'wrapper'" (i.e. public string CellValue), it calls SetValue directly.

So if you need to do something whenever a dependency property changes, you don't put it in set, like you do with normal properties. Instead, you register a PropertyChangedCallback. It will be called upon change, and the parameters contain both the old and new values for the property.

public string CellValue
{
    get { return (string)GetValue(CellValueProperty); }
    set { SetValue(CellValueProperty, value); }
}
public static readonly DependencyProperty CellValueProperty =
    DependencyProperty.Register("CellValue", typeof(string), typeof(control),
                                new PropertyMetadata(default(string), CellValue_Changed));

private static void CellValue_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ((control)d).MyNewValue = (string)e.NewValue;
}
Keith Stein
  • 6,235
  • 4
  • 17
  • 36