views:

81

answers:

2

Hello, if the parent's datasource has a child property that is a collection (let's say it is called ChildCollection) is there a trick to reference it?

So, this code sample is basically what I am attempting to do. But when I use this approach I do not get any data to my child controls.

<UserControl>
    <UserControl.Resources>
        <sample:Data x:Key="MyData" />
    </UserControl.Resources>
    <Canvas DataContext="{StaticResource MyData}">
        <TextBlock Text="{Binding Title}" />
        <My:UserControl DataContext="{Binding ChildCollection}" />
    </Canvas>
</UserControl>

My dependency property looks like this:

public static readonly DependencyProperty DataProperty =
    DependencyProperty.Register("Data", typeof(IEnumerable), typeof(ButtonList), 
    new UIPropertyMetadata(new PropertyChangedCallback(DataChanged)));
public DoubleCollection Data
{
    get { return (DoubleCollection)GetValue(DataProperty); }
    set { SetValue(DataProperty, value); }
}
static void DataChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    (sender as FrameworkElement).DataContext = e.NewValue;
}
public void SetData(IEnumerable data)
{
    (View as CollectionViewSource).Source = data;
}

Thank you in advance for your help.

A: 

If I understand your code right, you want the collection to be in the UserControl's DataProperty.

To achieve this, you have to do the Binding like this:

 <Canvas DataContext="{StaticResource MyData}">
    <TextBlock Text="{Binding Title}" />
    <My:UserControl Data="{Binding ChildCollection}" />
 </Canvas>

Instead of:

<Canvas DataContext="{StaticResource MyData}">
    <TextBlock Text="{Binding Title}" />
    <My:UserControl DataContext="{Binding ChildCollection}" />
 </Canvas>

Hope this is helpful. Also: I dont know if a canvas inherits it's DataContext to childs. Use a Panel instead (Grid/Stackpanel/WrapPanel).

Jan

JanW
PS: also try DynamicResource instead of StaticResource for your DataContext Binding on the Panel.
JanW
Canvas is derived from Panel. All FrameworkElements provide DataContext inheritance.
John Bowen
Thats not right. The Frame Component does not inherit its DataContext. As i did not test it with Canvas, i mentioned it.
JanW
A: 

Below is a working sample with a user control (ButtonList) that has a DP of type IEnumerable<double> and creates a button for each double value. Compare it to you code to see what you are doing incorrectly.

XAML:

<UserControl x:Class="UserControlDemo.ButtonList"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:UserControlDemo="clr-namespace:UserControlDemo"
    Name="_buttonList">
    <ItemsControl ItemsSource="{Binding Path=Data, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControlDemo:ButtonList}}}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Content="{Binding}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</UserControl>

Code behind:

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace UserControlDemo
{
    public partial class ButtonList : UserControl
    {
        public ButtonList()
        {
            InitializeComponent();
        }

        public IEnumerable<double> Data
        {
            get { return (IEnumerable<double>)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }

        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data",
                                        typeof(IEnumerable<double>), 
                                        typeof(ButtonList), 
                                        new UIPropertyMetadata(new List<double>()));
    }
}

Usage:

 <UserControlDemo:ButtonList Data="{Binding Path=Numbers}" />
Wallstreet Programmer