views:

2704

answers:

2

In Silverlight XAML, I think I've just realized that a DataContext declaration on a nested container is relative to the parent container's DataContext. Can you all please confirm.

If so, then let me ask this: On a child XAML container element (i.e. StackPanel) how would you would jump out of that relative DataContext tree, and start at a higher place, or a start a different DataContext all together if you wanted set the DataContext on the StackPanel to a different root context?

In other words, how to break the child DataContext free of the parent DataContext?

(Looking for XAML code solution/syntax)

+2  A: 

Your first assumnption is correct. The DataContext is kind of inherited by the nested elements.

On a child XAML container element you can always redefine what the DataContext is.

See example below:


    <UserControl.Resources>
        <local:Customer x:Key="Cust">
        <local:Supplier x:Key="Supp">
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource Cust}">
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Grid.Row="0">
            <TextBlock Text="Customer Name: " />
            <TextBox Text="{Binding Path=Name}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="1" DataContext="{StaticResource Supp}">
            <TextBlock Text="Supplier Name: " />
            <TextBox Text="{Binding Path=Name}"/>
            <TextBlock Text=" Telephone: " />
            <TextBox Text="{Binding Path=Telephone}"/>
        </StackPanel>
    </Grid>

And here are the "Model" classes for the example above:


    public class Customer
    {
        public Customer()
        {
            Name = "Customer name";
            Address = "Customer address";
        }
        public string Name { get; set; }
        public string Address { get; set; }
    }

    public class Supplier
    {
        public Supplier()
        {
            Name = "Supplier name";
            Address = "Supplier address";
            Telephone = "(555)555-5555";
        }

        public string Name { get; set; }
        public string Address { get; set; }
        public string Telephone { get; set; }
    }

Klinger
Your example creates the objects in the XAML. My objects are instantiated in the constructor. So, what XAML to use in each to point to the objects since they are not in the UserControl.Respources of the XAML.
MattSlay
Plus, I need persistent binding. Need something like this:<StackPanel DataContext="{Binding ExistingObjectFromConstructor.Cust}" ... />
MattSlay
If you don't want to use the XAML option, you can create a class that exposes an instance of other classes as public properties.You than bind this "presenter" to the "LayoutRoot" and use it'sproperties as the source for the other elements.
Klinger
this.Resource[".."] gives access (in code) to any named object defined within resources.When available, you can also bind the Source of an element to a property of the current DataContext
Klinger
How do you bind the LayoutRoot root to the presenter *FROM XAML*? I know how to set it in code, but would like to learn how to make XAML reference a presenter context. <StackPanel DataContext="{Binding What_Goes_Here?}" See my thread: http://silverlight.net/forums/t/77409.aspx for more info.
MattSlay
+1  A: 

Check out this blog, it details a proxy class for doing what you need all from xaml.

[http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx][1]

Mike