Member 12521151 Ответов: 2

Wpf-найдите элемент управления в headertemplate и отредактируйте его


Привет,
Я могу найти элемент управления в DataGridTemplateColumn объявленном в главном ресурсе
<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>

Подобный этому:
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
}

Но если я хочу изменить свойство (например, содержимое), то это изменение не происходит.
Я думаю, это потому, что шаблон загружен LoadContent().
Но если я этого не сделаю, то не смогу найти элемент управления внутри шаблона.

У вас есть решение ?

Что я уже пробовал:

//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().

2 Ответов

Рейтинг:
6

Pete O'Hanlon

Это то, чего вы должны быть в состоянии достичь практически полностью в XAML. В принципе, вы захотите поместить ContentPresenter вместо метки и скомпоновать метку в качестве содержимого по умолчанию. Затем вы просто переключите содержимое в зависимости от условия триггера внутри DataTemplate.

<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>
Я просто использую IsActive как демонстрацию того, что можно вызвать изменения в коде, просто реагируя на изменения привязки.


Member 12521151

Привет,
Да, я знаю триггеры, и они могут быть хорошим решением.
Но в моем случае, трудно, чтобы использовать его.
Я строю столбцы своего GridView динамически, и в некоторых случаях мне нужно использовать один и тот же шаблон
Моя viewmodel используется только для привязки строк datagrid.
Мои столбцы генерируются другим объектом (который находится в datacontext, но не в объекте, который привязан к datagrid).
я ищу, как я могу написать текст с помощью метода с индексом столбца, как параметр (в viewmodel, если это возможно), но я не нахожу его.

Pete O'Hanlon

Я не понимаю, как это так трудно использовать. На вашем месте я бы постарался использовать трюк, похожий на тот, который я описываю здесь: https://www.codeproject.com/Tips/211113/MVVM-Friendly-DataTemplate-switching

Member 12521151

Я француженка,может быть, я неправильно объясняю.
Моя DataGrid привязана к списку объектов для генерации строк.
И мои столбцы генерируются с кодом позади с другим объектом, который не известен Xaml (но это возможно).
Поэтому я не могу использовать свойство, которое не сопоставлено с datagrid.
кроме того, мне нужно знать индексную позицию столбца для идентификации текста заголовка.
По этим двум причинам идеальным решением будет привязка с помощью метода, но у меня есть трудности.

Рейтинг:
19

Richard Deeming

Один DataTemplate определяет шаблон для группы элементов управления.

Когда вы звоните LoadContent, вы создаете экземпляр дерева элементов управления, определенного в шаблоне. Затем ваш код изменяет этот единственный экземпляр, а затем выбрасывает его.

В следующий раз, когда что-то использует DataTemplate чтобы создать экземпляр дерева управления, ваши изменения отсутствуют, потому что вы изменили экземпляр дерева управления, а не сам шаблон.

Вы вероятно уметь сверлить в colModel.HeaderTemplate.VisualTree чтобы найти и изменить элемент, предположим, что шаблон не запечатан к тому времени, когда вы доберетесь до него. Или вы можете создать шаблон с помощью кода , но это намного сложнее, чем сделать это с помощью XAML.

Лучший вариант-найти другой способ внести необходимые изменения.


Member 12521151

Привет,

HeaderTemplate.VisualTree имеет значение null перед LoadContent () и не существует в ответ на LoadContent ().

Я просто хочу использовать "rowRegroupement" как универсальную модель.

Не могли бы вы дать мне дополнительную информацию или пример, пожалуйста.

Richard Deeming

Тогда вам нужно будет найти другой способ внести необходимые изменения. Посмотрите на использование привязки и / или триггеров в разметке XAML для обновления текста в шаблоне по мере необходимости.