0
votes

I am binding a treeview using a Hierarchical class structure as follows.

Store ->ImagePath ->List ->List

When I am creating the DataTemplate for the Person, I want to use a combination of the person.name and the image path declared in the Store. Here is the code behind of my MainWindow.xaml file. ` public partial class MainWindow : Window { public MainWindow() { InitializeComponent();

        Customers customers = new Customers();
        customers.Users = new List<Person> 
        { 
            new Person { Name = "John"},
            new Person { Name = "Adam"}, 
            new Person { Name = "Smith"}
        };

        Store root = new Store();
        root.ImagePath = "imageone.png";
        root.Add(customers);
        this.DataContext = root;
    }
}


public class Store : ObservableCollection<Customers> 
{
    public string ImagePath
    {
        get;
        set;
    }
} 
public class Customers
{
    public string Label
    {
        get
        {
            return string.Format("People({0})", Users.Count());
        }
    }
    public List<Person> Users
    {
        get;
        set;
    } 
}
public class Person
{
    public string Name
    {
        get;
        set;
    }
}`

and here is the xaml and this Source="{Binding Store.ImagePath}" is not working.

    <Window.Resources >
   <DataTemplate DataType="{x:Type local:Person}" x:Key="personKey" >
        <StackPanel Orientation="Horizontal" >
            <Image Source="{Binding Store.ImagePath}"></Image>
            <TextBlock Text="{Binding Name}" />
        </StackPanel>
    </DataTemplate>
    <HierarchicalDataTemplate x:Key="customerKey" ItemsSource="{Binding Users}" ItemTemplate="{StaticResource personKey }" >
        <TextBlock Text="{Binding Label}" FontWeight="Bold"/>
    </HierarchicalDataTemplate>
</Window.Resources>
<Grid>
    <Canvas>
        <Button HorizontalAlignment="Left" DockPanel.Dock="Top" Height="29" Width="112" Canvas.Left="123" Canvas.Top="5">Image one</Button>  <Button HorizontalAlignment="Left" VerticalAlignment="Top" DockPanel.Dock="Top" Height="28" Width="119" Canvas.Left="249" Canvas.Top="7">Image two</Button>
        <TreeView  HorizontalAlignment="Stretch"  Name="treeView1" VerticalAlignment="Stretch" 
               ItemsSource="{Binding .}" ItemTemplate="{StaticResource customerKey}" Height="260" Width="363" Canvas.Left="81" Canvas.Top="45" />
    </Canvas>
</Grid>

I would also like to change the image programaticaaly and all person treeview items change when I click on of the buttons.

Thanks

1

1 Answers

1
votes

The DataTemplate personKey is going to get bound to a Person object (because it's the ItemTemplate for the customerKey HierarchicalDataTemplate, whose ItemsSource is the Users collection). As always in WPF, the local DataContext overrides the inherited DataContext, and the DataContext within a DataTemplate is always the object for which the DataTemplate is being materialised.

So the binding path Store.ImagePath is being resolved relative to the Person being displayed in the DataTemplate. But Person doesn't have a Store property, so the binding fails.

A quick but rather kludgy way to refer to window-level properties is by using a RelativeSource binding:

<Image Source="{Binding Path=DataContext.Store.ImagePath,
                        RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />