Is it possible to parameterize the binding on a DataGrid CellTemplate in a resource?

Refresh

December 2018

Views

1k time

4

I'm putting together some generic CellTemplate styles for a WPF grid (WPFToolKit DataGrid), and I’m not sure of the syntax to use to make the binding generic. So for example, I have this template, which turns the value red if the value is negative:

<DataTemplate x:Key="RedNegativeCellTemplate">
    <TextBlock Name="QuantityTextBox" Text="{Binding Quantity, StringFormat='c', Mode=OneWay}"/>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Quantity, Converter={StaticResource SignConverter}}" Value="-1">
            <Setter TargetName="QuantityTextBox" Property="Foreground" Value="Red"/>
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

You’ll notice that this has a binding on the Text box to the column value ‘Quantity’ - i.e., the field/column that the binding comes from is explicit.

So I can use this in my WPF DataGrid as follows:

<sdk:DataGrid ItemsSource="{Binding MyDataSource}" AutoGenerateColumns="False">
    <sdk:DataGrid.Columns>

        <sdk:DataGridTemplateColumn Header="Net Quantity" CellTemplate="{StaticResource RedNegativeCellTemplate}"/>

    </sdk:DataGrid.Columns>
</sdk:DataGrid>

But… what I’d really like to do is to have the field binding generic for the template, so that I can re-use the template as follows:

<sdk:DataGrid ItemsSource="{Binding OrdersQuery}"AutoGenerateColumns="False">
    <sdk:DataGrid.Columns>
        <sdk:DataGridTemplateColumn Header="Quantity" CellTemplate="{StaticResource RedNegativeCellTemplate}"/>
        <sdk:DataGridTemplateColumn Header="Price" CellTemplate="{StaticResource RedNegativeCellTemplate}"/>
        <sdk:DataGridTemplateColumn Header="Total" CellTemplate="{StaticResource RedNegativeCellTemplate}"/>
    </sdk:DataGrid.Columns>
</sdk:DataGrid>

Now, the problem here is that there doesn't seem to be a way to parameterize the binding in the CellTemplate. But I'm loath to have to have 3+ lines of controltemplate for every column that uses this template, as it clutters the XAML and makes it far less readable (not to mention the fact that if I decide to change the cell template to put a border around the textbox, I'd have to modify it in multiple places.

So I'm thinking that the binding within the CellTemplate should look something like this (note that we're using '.' for the binding path):

            Text="{Binding Path=., StringFormat='c', Mode=OneWay}"

And then somehow set the datacontext from the DataGridTemplateColumn declaration – but I can’t see how to do it.

Any idea how to do this?

2 answers

0

Для этого вы можете использовать , DataTemplateSelectorкоторый на самом деле довольно просто реализовать.
Если вам нужны дополнительные пояснения и примеры - дайте мне знать.

1

@Webreaper: Если я правильно понял вашу идею правильно, то вы и я бегу в тот же самый материал. Я не пробовал мой вариант решения, в основном, я связать свойство пути привязки к SortMemberPath в DataGridTemplateColumn в.

<DataGrid>
....
     <DataGridTemplateColumn CellTemplate={StaticResource CellTemplateKey} />
....
</DataGrid>

Где CellTemplateKey определяется где-то (в App.xaml, например):

<DataTemplate x:Key="CellTemplateKey">
    <TextBlock Binding="{Binding Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}, Path={Binding Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridTemplateColumn, Path=SortMemberPath}}}}" />
</DataTemplate>

Я буду проверять и обновлять это позже. Я надеюсь, что эта идея полезна каким-то образом. Я могу смотреть на Dyna