Question

I have the following DataTemplate in resources that I would like to reuse throughout a GridView.

<Window.Resources>
  <DataTemplate x:Key="NumericalDataTemplate" DataType="GridViewColumn.CellTemplate">
     <StackPanel Orientation="Horizontal" Height="32">
       <TextBlock Text="{Binding MyLength}" VerticalAlignment="Center"
                     HorizontalAlignment="Center">
         <TextBlock.Style>
            <Style TargetType="{x:Type TextBlock}" >
               <Setter Property="Visibility" Value="Visible" />
               <Style.Triggers>
                 <DataTrigger Binding="{Binding PropertyEditable}" Value="True">
                    <Setter Property="Visibility" Value="Collapsed" />
                 </DataTrigger>
               </Style.Triggers>
           </Style>
         </TextBlock.Style>
       </TextBlock>
    </StackPanel>
  </DataTemplate>
</Window.Resources>

Which is implemented as follows.

<GridViewColumn Header="MyLength" Width="80" 
                CellTemplate="{StaticResource NumericalDataTemplate}" />

I would like change the Binding of the TextBlock (Currently Text={Binding MyLength} ) so that it can use a custom binding for each GridViewColumn Cell Template (eg MyHeight, MyWeight etc).

The way I envisaged doing this is changing the Binding of the TextBlock to simply use {Binding} and having the GridViewColumn set the Binding. However, I'm not sure where or how to do this, as setting the DisplayMemberValue to {Binding MyLength} (for example) simply overrides the template.

I would preferably like to do this entirely in XAML.

Was it helpful?

Solution

It seems that CellTemplate will always be ignored when we have DisplayMemberBinding property set. Possible workaround for this limitation is, by creating markup-extension as pointed by @H.B in his answer to similar question here. Creating markup-extension involves C#/VB codes, but using it only needs XAML codes.

You can reuse the same markup-extension C# code provided by @H.B. Then to use it in your XAML, declare namespace prefix :

<Window ......
    xmlns:local="clr-namespace:WpfProject">

Modify DataTemplate key and binding of the TextBlock inside :

<DataTemplate x:Key="TemplateBuilder_BaseTemplate" DataType="GridViewColumn.CellTemplate">
    <StackPanel Orientation="Horizontal" Height="32">
        <TextBlock Text="{local:TemplateBuilderTag}" VerticalAlignment="Center"
                   HorizontalAlignment="Center">
            <TextBlock.Style>
                <Style TargetType="{x:Type TextBlock}" >
                    <Setter Property="Visibility" Value="Visible" />
                    <Setter Property="Foreground" Value="Red"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding PropertyEditable}" Value="True">
                            <Setter Property="Visibility" Value="Collapsed" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
    </StackPanel>
</DataTemplate>

Now you can use the same DataTemplate for different column binidngs :

<GridView.Columns>
    <GridViewColumn Header="MyLength" Width="80"
            CellTemplate="{local:TemplateBuilder MyLength}" />
    <GridViewColumn Header="MyHeight" Width="80" 
            CellTemplate="{local:TemplateBuilder MyHeight}" />
</GridView.Columns>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top