views:

110

answers:

1

Hi Everyone,

I need to bind two-way a property of a user control to a property of a containing user control. I also need to set a default value to the property from code in the child (cannot be done easily from XAML tags).

If I call my code from the child constructor, the value is set in the parent but the change callback routine is not triggered (my understanding is that the parent doesn't yet exist at the time the child is created).

My current workaround is to catch the Loaded event of the child and to call the code from the handler. Howver as Loaded is called more than once, I need to set a flag to set the property only the first time. I don't like this way, but I don't know if there is a single shot event that could be used, or if this can be done otherwise. Any feedback based on your experience?

A: 

For the default value use the DependencyProperty and pass in FrameworkPropertyMetadata object containing the default value, e.g.

    public static readonly DependencyProperty ProductNameProperty =
            DependencyProperty.Register(
                "ProductName",
                typeof(string),
                typeof(ProductTextBox),
                new FrameworkPropertyMetadata(null, // Default Value
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                    new PropertyChangedCallback(ChangeProductName)) );

If the default value is variable per instance and differs then maybe a combination of

SetValue(ProductNameProperty, value_required); 
PropertyChanged(this, new PropertyChangedEventArgs("ProductName")); 

Possibly both in the constructor or send the PropertyChanged in the loaded event if it doesn't work in the constructor. I've not actually tried this...

Richard Harrison
Thanks Richard. In my parent UserControl, I bind the child property Step to the parent property Step in xaml using "Step="{Binding ElementName=ui_UserControl, Path=Step, Mode=TwoWay}", ui_UserControl being "this" UserControl. So I bind in the source rather than in the target. I can set the value in the child using SetValue (second suggestion). Which object/type PropertyChanged would belong in this case?
742
I've already a default value defined for the property Step, both in the child and the parent. But it doesn't trigger the parent PropertyChanged callback. That's where is my problem.
742
When the property is changed by the owner it should be done via SetValue / PropertyChanged - and the bindings will update. However it may be better to do this by having another object to manager the state..
Richard Harrison
Richard, I know how to use SetValue/GetValue. My understanding is that when the value is changed, the DP system will issue an event so that the bindings will work. I don't get what would PropertyChanged(this, new PropertyChangedEventArgs("ProductName")); has to do here, it seems to be a seperate CLR event that I should add to my child user control and raise with this code. But to be useful, I would need to register to this event notification and react in the parent UC. But this is independent from the DP. If this is wrong, I don't understand.
742