开发者

Nested Binding of UserControls

I am having trouble getting the following scenario to work (this code is not the actual code but the principals are the same. Basically I need to pass a value down from a MainPage down to a nested "reusable user control" that binds to it's own properties. I want to see the "This is it!" text on the screen but it's not being set in the SilverlightControl2 control (I suspect due to the setting of the DataContext) - but I how do I fix it?

MainPage.xaml

<Grid>
    <ContentPresenter>
        <ContentPresenter.Content>
            <Local:SilverlightControl1 OneValue="This is it!"/>
        </ContentPresenter.Content>
    </ContentPresenter>
</Grid>

SilverlightControl1.xaml

<Grid>
    <Local:SilverlightControl2 TwoValue="{Binding OneValue}"/>
</Grid>

SilverlightControl1.xaml.cs

public partial class SilverlightControl1 : UserControl
{
    public string OneValue
    {
        get { return (string)GetValue(OneValueProperty); }
        set { SetValue(OneValueProperty, value); }
    }

    public static readonly DependencyProperty OneValueProperty = DependencyProperty.Register(
        "OneValue", typeof(string), typeof(SilverlightControl1), new PropertyMetadata(string.Empty));

    public SilverlightControl1()
    {
        InitializeComponent();
        this.DataContext = this;
    }
}

SilverlightControl2.xaml

<Grid x:Name="LayoutRoot" Background="White">
    <TextBlock Text="{Binding TwoValue}"  Foreground="Blue" />
</Grid>

SilverlightControl2.xaml.cs

public partial class SilverlightControl2 : UserControl
{
    public string TwoValue
    {
        get { return (string)GetValue(TwoValueProperty); }
        set { SetValue(TwoValueProperty, value); }
    }

    public static readonly DependencyProperty TwoValueProperty = DependencyProperty.Register(
        "TwoValue", typeof(string), typeof(SilverlightControl2), new PropertyMetadata(string.Empty));


    public SilverlightContro开发者_如何学Gol2()
    {
        InitializeComponent();
        this.DataContext = this;
    }
}


As soon as you find yourself feeling the need to do this:-

this.DataContext = this; 

know that you have probably got things wrong. Its probably the first thing I would expect to find on Silverlight specific "bad smell list".

In this case where you are specialising UserControl a better approach is to do this:-

SilverlightControl1.xaml

<Grid>         
    <Local:SilverlightControl2 x:Name="MyControl2" />         
</Grid>

SilverlightControl1.xaml.cs (I'm just showing the constructor the rest is as you have it)

public SilverlightControl1()  
{  
    InitializeComponent();  
    MyControl2.SetBinding(SilverlightControl2.TwoValueProperty , new Binding("OneValue") { Source = this });

} 

SilverlightControl2.xaml

<Grid x:Name="LayoutRoot" Background="White">               
    <TextBlock x:Name="MyTextBox"  Foreground="Blue" />               
</Grid> 

SilverlightControl1.xaml.cs (I'm just showing the constructor the rest is as you have it)

public SilverlightControl2()  
{  
    InitializeComponent();  
    MyTextBox.SetBinding(TextBox.TextProperty , new Binding("TwoValue") { Source = this });  
} 

Since in UserControls you know the structure of the XAML and you can name the elements that you need access to in code, you can create the binding using a line of code instead. This leaves the DataContext free to do what is designed for rather than be hi-jacked for a different purpose.

The alternative approach where instead of specialising UserControl you create a templated control, in this case the binding can be expressed in XAML using something like:-

<TextBox Text="{TemplateBinding TwoValue}" />

Template binding only works in ControlTemplate so you can't use it in a UserControl.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜