Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Silverlight: Binding a child controls property to a property in a user control

If I have a user control defined:

public partial class MainFooter : UserControl
{
    public System.Windows.Media.Color BkColor;
}

and it's xaml:

<UserControl x:Class="Test.MainFooter">
    <Grid x:Name="LayoutRoot">
        <Rectangle x:Name="rctBottom_Background2"
                   HorizontalAlignment="Stretch" 
                   Grid.Row="2">
            <Rectangle.Fill>
                <LinearGradientBrush EndPoint="0.82,0.895" StartPoint="0.911,-0.442">
                    <GradientStop Color="{**How can I bind this to the BkColor property?}"/**>
                    <GradientStop Color="#00FFFFFF" Offset="1"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
    </Grid>
</UserControl>

and used:

<MyControls:MainFooter x:Name="rcrMainFooter"
                       BkColor="#FFE2B42A">
</MyControls:MainFooter>

How would I go about binding the GradientStop Color in the Rectangle to the value of the it's user controls BkColor property?

like image 334
Jeremy Avatar asked Jan 07 '09 18:01

Jeremy


2 Answers

Often when I've seen this question posed the answer is 'you have to do it in code', which sounded to me like 'Silverlight binding doesn't support this' - so you have to do it 'completely manually' by setting the property by hand. But thats not the case :

Silverlight binding does support this - its just Silverlight XAML that doesn't.

Here's an example of a UserControl that basically wraps a DataForm. In the constructor you run the binding which can bind to your 'user control property'. Hopefully if they change the XAML support for this in future then it'll be trivial to come back and fix.

App.xaml

<AddressControl MyHeader="Shipping Address"/>

AddressControl.xaml

<UserControl>
    <DataForm Name="dfAddress" Header="BOUND IN CODE"/>
</UserControl>

Optional: indidicate that you've bound the value in code with a comment

AddressControl.xaml.cs

publicAddressControl()
{
    InitializeComponent();

    // bind the HeaderProperty of 'dfAddress' to the 'MyHeader' dependency
    // property defined in this file
    dfAddress.SetBinding(DataForm.HeaderProperty, 
    new System.Windows.Data.Binding { Source = this, 
                                      Path = new PropertyPath("MyHeader") });
}

// standard string dependency property
public string MyHeader
{
    get { return (string)GetValue(MyHeaderProperty); }
    set { SetValue(MyHeaderProperty, value); }
}

public static readonly DependencyProperty MyHeaderProperty = 
       DependencyProperty.Register("MyHeader", typeof(string), 
       typeof(AddressControl), null);

This binds the MyHeader property on my AddressControl usercontrol to the Header property on the dataform. I made it 'My' solely for easy readability - but I'm actually using just 'Header' in my real code.

Real shame we still can't do this in XAML, but its better than what I first attempted which was to capture the DataContextChanged events and then manually set things.

like image 77
Simon_Weaver Avatar answered Nov 15 '22 21:11

Simon_Weaver


The only way is to do it programically (e.g. in the change event for the BkColor (assuming its a DependencyProperty) change it in the other places on your control. Alternatively you could use a ControlTemplate and use TemplateBinding. If your UserControl is a workaround for this (e.g. no behavior/methods/events), then replace your user control with a ContentControl and use Template Bindng.

like image 30
Shawn Wildermuth Avatar answered Nov 15 '22 21:11

Shawn Wildermuth