Click here to Skip to main content
15,884,099 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,
I can find a control in DataGridTemplateColumn declared in main resource
XML
<DataGridTemplateColumn x:Key="rowRegroupement"  MinWidth="140" Width="1*">
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Label x:Name="lblRegLib" Grid.Row="0" Content="{x:Static resx:resTabBord.lblAchatsBud}"/>
                <Rectangle Grid.Row="1" Fill="{StaticResource scbGrey2}" Margin="-7, 2" Height="1.5" />
                <TextBox x:Name="txtRegLib" Grid.Row="2" Margin="2" Height="24" Visibility="{Binding ElementName=ucTabBord, Path=ModeAff, Converter={StaticResource BoolToVisibility}, ConverterParameter=true}"/>
            </Grid>
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>

Like this:
C#
var colModel = (DataGridTemplateColumn)this.Resources["rowRegroupement"];
var tpl = colModel.HeaderTemplate.LoadContent(); // Instanciation du template pour pouvoir parcourir ses controls
var ctrls = Classes.clsUtils.FindVisualChildren<Label>(tpl);
foreach (var ctrl in ctrls) {
    ((Label)ctrl).Content = "TEST"; // KO
}

But if i want change a property (content by example), the change don't occurs.
I thing it's because the template is loaded with LoadContent().
But if i don't made this, i can't find a control inside template.

Do you have a solution ?

What I have tried:

C#
//ucDataGridColHead uc = ((ucDataGridColHead)ctrl);
//uc.Title = Col.BddNomTable; // Ne fonctionne pas car les controls sont déjà mappés avec LoadContent().
//var lblTitre = uc.FindName("lblTitre");
//if (lblTitre != null) { ((System.Windows.Documents.Run)lblTitre).Text = Col.BddNomTable; } // Ne fonctionne pas car les controls sont déjà mappés avec LoadContent().
Posted
Updated 7-Dec-16 2:11am

A DataTemplate defines a template for a group of controls.

When you call LoadContent, you create an instance of the control tree defined within the template. Your code then modifies that single instance, and then throws it away.

The next time something uses the DataTemplate to create an instance of the control tree, your changes are not there, because you changed an instance of the control tree, not the template itself.

You might be able to drill into the colModel.HeaderTemplate.VisualTree to find and modify the element, assuming the template isn't sealed by the time you get to it. Or, you might be able to create the template through code - but that's a lot more complicated than doing it through XAML.

The best option is to find another way to make the changes you need.
 
Share this answer
 
Comments
Member 12521151 7-Dec-16 3:32am    
Hello,

HeaderTemplate.VisualTree is null before LoadContent() and don't exist in return of LoadContent().

I just want use "rowRegroupement" like a generic model.

Could you give me more information or an exemple, please.
Richard Deeming 7-Dec-16 8:03am    
Then you'll need to find another way to make the changes you need. Look at using binding and/or triggers in the XAML markup to update the text within the template as required.
This is something you should be able to achieve pretty much entirely in XAML. Basically, you're going to want to put a ContentPresenter in the place of the Label and composite a Label as the default content in there. Then, you're just going to switch the Content depending on a trigger condition inside the DataTemplate.
XML
<DataGridTemplateColumn x:Key="rowRegroupement"  MinWidth="140" Width="1*">
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Label x:Name="lblRegLib" Grid.Row="0" Content="{x:Static resx:resTabBord.lblAchatsBud}"/>
                <Rectangle Grid.Row="1" Fill="{StaticResource scbGrey2}" Margin="-7, 2" Height="1.5" />
                <TextBox x:Name="txtRegLib" Grid.Row="2" Margin="2" Height="24" Visibility="{Binding ElementName=ucTabBord, Path=ModeAff, Converter={StaticResource BoolToVisibility}, ConverterParameter=true}"/>
            </Grid>
            <DataTemplate.Triggers>
              <DataTrigger Binding="{Binding IsActive}" Value="True">
                <Setter TargetName="lblRegLib" Property="Content" Value="Test" />
              </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>
I am just using IsActive as a demonstration that it's possible to trigger changes in the code just by responding to binding changes.
 
Share this answer
 
Comments
Member 12521151 8-Dec-16 6:41am    
Hello,
Yes, i Know triggers, and they may be a good solution.
But in my case, it's difficult to use it.
I build the columns of my GridView dynamically, and in some case, i need to use the same template
My viewmodel is used only for binding datagrid rows.
My columns are generated by another object (who is in datacontext, but not in object who is binded to datagrid).
i search how i can write text with a method with index of column like parameter (in viewmodel if possible), but i don't find it.
Pete O'Hanlon 8-Dec-16 6:49am    
I don't see how it's that difficult to use. If I were you, I would look to use a trick similar to the one that I describe here: https://www.codeproject.com/Tips/211113/MVVM-Friendly-DataTemplate-switching
Member 12521151 8-Dec-16 8:35am    
I'm French, maybe I'm explaining myself wrong.
My DataGrid is binded on a list of object for generate rows.
And my columns are generated with code behind with another object, who is not know by Xaml (but it's possible).
So i can't use a property who is not mapped with datagrid.
moreover, i need to know the index position of column for identifiate the header text.
For this two reasons, the ideal solution will be to binding with a method, but i have difficulties.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900