WPF Templates and binding to DataContext in a GridView
Asked Answered
B

1

6

I'm trying to create a series of bound columns in a RadGridView, and I'm using a template to create hyperlinks in two of the columns. Here is basically what I have:

<telerik:GridViewDataColumn IsReadOnly="True" UniqueName="Distributor" DataContext="{Binding Distributor}" CellTemplate="{StaticResource linkTemplate}"/>

and,

    <DataTemplate x:Key="linkTemplate">
        <TextBlock>
            <Hyperlink DataContext={TemplateBinding DataContext} Click="Hyperlink_Click">
                <TextBlock Text="{Binding Name}" />
            </Hyperlink>
        </TextBlock>
    </DataTemplate>

The RadGridView itself is bound to a set of DistributorContainer objects that have, among other things, a Distributor property. The linkTemplate refers directly to properties in the Distributor object, so the hyperlink's datacontext needs to be set to the Distributor.

Unfortunately, the Hyperlink's data context is the DistributorContainer object. I'm using the linkTemplate (as well as the Hyperlink_Click handler) on lists that bind to lists of Distributors, and I'd really like to re-use this template since it's basically the same thing.

Why isn't the template getting the Distributor as its DataContext through the TemplateBinding to the GridViewDataColumn?

Bronchiole answered 3/3, 2010 at 0:14 Comment(0)
Z
10

Here is an example how to achieve this:

XAML

<Grid>
    <Grid.Resources>
        <DataTemplate x:Key="linkTemplate">
            <TextBlock>
                <Hyperlink>
                    <TextBlock 
                        Text="{Binding 
                            Value.Name, 
                                RelativeSource={RelativeSource FindAncestor, 
                                AncestorType={x:Type telerik:GridViewCell}}}" />
                </Hyperlink>
            </TextBlock>
        </DataTemplate>
    </Grid.Resources>
    <telerik:RadGridView ItemsSource="{Binding}" AutoGenerateColumns="False">
        <telerik:RadGridView.Columns>
            <telerik:GridViewDataColumn 
                DataMemberBinding="{Binding Distributor1}" 
                CellTemplate="{StaticResource linkTemplate}" />
            <telerik:GridViewDataColumn 
                DataMemberBinding="{Binding Distributor2}" 
                CellTemplate="{StaticResource linkTemplate}" />
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>
</Grid>

C#

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            DataContext = 
                from i in Enumerable.Range(0, 10)
                select new DistributorContainer()
                {
                    ID = i,
                    Distributor1 = new Distributor() { 
                        Name = String.Format("Distributor1 Name{0}", i) },
                    Distributor2 = new Distributor() { 
                        Name = String.Format("Distributor2 Name{0}", i) }
                };
        }
    }

    public class DistributorContainer
    {
        public int ID { get; set; }
        public Distributor Distributor1 { get; set; }
        public Distributor Distributor2 { get; set; }
    }

    public class Distributor
    {
        public string Name { get; set; }
    }
}
Zellazelle answered 4/3, 2010 at 8:15 Comment(2)
This does work and provides a means of using a single template for any gridview, but is there a way to just bind to the DataContext of the templated parent? This would give the template a lot more flexibility.Bronchiole
Since DataContext of the templated parent (cell in this case) is the same as DataContext of the row you cannot achieve desired result in this way.Zellazelle

© 2022 - 2024 — McMap. All rights reserved.