Houman
Houman

Reputation: 66320

Silverlight: How to bind to parent view's DataContext?

I have a ParentView that contains a childView

<UserControl ... x:Name="MyParentView">
     <Grid>
        <sdk:TabControl Name="ContactTabControl">
            <sdk:TabItem Header="Contact" Name="CustomerTabItem">
                <Grid>
                    <Views:CustomerView/>
                </Grid>
            </sdk:TabItem>
        </sdk:TabControl>
    </Grid>
</UserControl>

Within my CustomerView I would like to bind the Firstname textbox to Parent's DataContext. I have tried this inside the CustomerView:

<TextBox Text={Binding ElementName=MyParentView, Path=DataContext.Firstname} />

I have the feeling that CustomerView won't be able to see its parent at all, hence the ElementName "MyParentView" would never be found.

What is your advice on this?

Upvotes: 1

Views: 8548

Answers (2)

Maciek
Maciek

Reputation: 19893

An alternative solution to Maverik's is :

1 Define a dependency property in your customer view :

public partial class CustomerView : UserControl
    {
        public CustomerView()
        {
            InitializeComponent();
        }

        public static DependencyProperty FirstNameProperty =
            DependencyProperty.Register("FirstName", typeof(string), typeof(CustomerView), new PropertyMetadata(string.Empty, CustomerView.FirstNameChanged));

        public string FirstName
        {
            get { return (string)GetValue(FirstNameProperty); }
            set { SetValue(FirstNameProperty, value); }
        }

        private static void FirstNameChanged(object sender, DependencyPropertyChangedEventArgs e)
        { }
    }

2 Modify the customer view's textbox to bind to this dependency property (note the element binding "this")

<UserControl x:Class="SLApp.CustomerView"
    x:Name="this"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox Text="{Binding Path=FirstName, ElementName=this, Mode=TwoWay}"/>
    </Grid> </UserControl>

3 Modify the parent view and bind it's DataContext to the new dependency property

<sdk:TabControl Name="ContactTabControl">
                        <sdk:TabItem Header="Contact" Name="CustomerTabItem">
                            <Grid>
                                <local:CustomerView FirstName="{Binding ElementName=ContactTabControl, Path=DataContext}"/>
                            </Grid>
                        </sdk:TabItem>
                    </sdk:TabControl>

4 Set the parent's DataContext

public partial class MyParentView : UserControl
    {
        public MyParentView()
        {
            InitializeComponent();

            ContactTabControl.DataContext = "A name";
        }
    }

Voila' it works. Not the most elegant solution but it gets the job done for your scenario

Upvotes: 2

Maverik
Maverik

Reputation: 5671

I've done a similar thing but I just bound it directly to Path considering that if I don't give it explicit data context, it will lookup the hierarchy and find one that matches.

So this should get you what you want:

<TextBox Text={Binding Path=FirstName} />

if you need to specify explicit datacontext you can always do:

<Grid>
    <Views:CustomerView DataContext={"CustomContextHere"}/>
</Grid>

Upvotes: 4

Related Questions