tags:

views:

470

answers:

2

I have a DataTemplate that I'm using as the CellTemplate for a GridViewColumn.

I want to write something like this for the DataTemplate:

<DataTemplate
    x:Key="_myTemplate">
    <TextBlock
        Text="{Binding Path={Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GridViewColumn}}, Path=Header}}" />
</DataTemplate>

My GridView is bound to a DataTable, and I want to bind to the column of the DataTable whose name is equal to the Header of the GridViewColumn the DataTemplate is attached to. [I hope that made sense!]

Unfortunately, this doesn't work. I get a XamlParseException: "A 'Binding' cannot be set on the 'Path' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependenceyObject."

How can I set this up?

Edit (elevating comment by DanTheMan to the question)

I basically need a DataTemplate whose binding is determined by the DataContext and which column the DataTemplate is attached to. Is there an alternative?

A: 

You cannot assign a Binding to just any property. The property must either of the type Binding or be implemented as a Dependency Property on the object.

The Path property of the Binding class is of type PropertyPath and Binding does not implement the Path property as a dependency property. Hence you cannot dynamically bind the Path in the way you are attempting to.

Edit

You basically want to embed metadata in your bound data which drives the configuration of the DataTemplate. This can't be done in XAML alone. You would need at least some support from code.

It would seem to me that the best approach would be to use a ViewModel. That makes the binding in the XAML straight-forward and pushes this "what to bind with what" decision down into the code of the ViewModel.

AnthonyWJones
Thanks, but my question is whether there's another way to accomplish my goal using XAML. I basically need a DataTemplate whose binding is determined by the DataContext *and* which column the DataTemplate is attached to. Is there an alternative?
DanM
@Anthony, Thx for your edit. My question actually came out of a discussion on how to show pivot data in a GridView where the number of columns and associated binding paths are not known until the database is queried at runtime. I am using MVVM and do have a ViewModel, but my initial solution was to generate DataTemplates dynamically in the codebehind using XamlReader.Load(). This was roundly criticized as "not good" (see http://stackoverflow.com/questions/1156336/is-it-possible-to-configure-a-gridview-to-show-pivoted-data-using-static-xaml-if), hence my attempt at a more flexible DataTemplate.
DanM
@Anothony (continued), So my DataContext is set to my ViewModel, and my GridView's ItemsSource is set to a property of the ViewModel (a DataTable), but I guess I don't understand how the ViewModel can solve the problem of how to map each GridViewColumn to the correct DataTable column without resorting to dynamically loaded XAML.
DanM
A: 

Don't you just want this?

{Binding Path=Header, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GridViewColumn}}}
Bryan Anderson
I believe what you have here would set the text box of every single cell in the column to be the same as the Header. What I want is to bind the GridViewColumn to the appropriate DataColumn of a DataTable, where the names of the columns in the DataTable match the Header value of the GridViewColumns. So, if the Header for a GridViewColumn were "Column3", this column would be bound to the column named "Column3" in the DataTable. I hope that makes sense :)
DanM
I think you will have problems doing it the way you're trying to since GridViews are row-based, i.e. a cell is a child or a row, not a column. Try looking at this series of posts by Dr. WPF, it might help clear up some confusion: http://drwpf.com/blog/ItemsControlSeries/tabid/59/Default.aspx. A basic rule of thumb for WPF, if you're trying to use something in a way it wasn't designed for things will get incredibly difficult, but they usually have an easy way to do it already made. It's finding the easy way that's the hard part...
Bryan Anderson
@Bryan I'll take a look, thanks!
DanM