Подтвердить что ты не робот

Ошибка WPF: не удается найти управляющий элемент FrameworkElement для целевого элемента

У меня есть datagrid с Row, у которого есть изображение. Это изображение связано с триггером для определенного состояния. Когда изменяется состояние, я хочу изменить изображение.

Сам шаблон устанавливается в HeaderStyle элемента DataGridTemplateColumn. Этот шаблон имеет некоторые привязки. Первый день привязки показывает, что это за день, и государство меняет изображение с помощью триггера.

Эти свойства задаются в ViewModel.

Свойства:

public class HeaderItem
{
    public string Day { get; set; }
    public ValidationStatus State { get; set; }
}

this.HeaderItems = new ObservableCollection<HeaderItem>();
        for (int i = 1; i < 15; i++)
        {
            this.HeaderItems.Add(new HeaderItem()
            {
                Day = i.ToString(),
                State = ValidationStatus.Nieuw,
            });
        }

Datagrid:

<DataGrid x:Name="PersoneelsPrestatiesDataGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
              AutoGenerateColumns="False" SelectionMode="Single" ItemsSource="{Binding CaregiverPerformances}" FrozenColumnCount="1" >

    <DataGridTemplateColumn HeaderStyle="{StaticResource headerCenterAlignment}" Header="{Binding HeaderItems[1]}" Width="50">

                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox Text="{ Binding Performances[1].Duration,Converter={StaticResource timeSpanConverter},Mode=TwoWay}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock TextAlignment="Center" Text="{ Binding Performances[1].Duration,Converter={StaticResource timeSpanConverter}}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn> </DataGrid>

Datagrid HeaderStyleTemplate:

  <Style x:Key="headerCenterAlignment"
          TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="HorizontalContentAlignment" Value="Center"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>

                        <TextBlock Grid.Row="0" Text="{Binding Day}" />
                        <Image x:Name="imageValidation" Grid.Row="1" Width="16" Height="16" Source="{StaticResource imgBevestigd}" />
                    </Grid>

                    <ControlTemplate.Triggers>
                        <MultiDataTrigger >
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding State}" Value="Nieuw"/>                                 
                            </MultiDataTrigger.Conditions>
                            <Setter TargetName="imageValidation" Property="Source" Value="{StaticResource imgGeenStatus}"/>
                        </MultiDataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Теперь, когда я запускаю проект, изображения не отображаются, и я получаю эту ошибку:

Ошибка System.Windows.Data: 2: Не удается найти управляющий элемент FrameworkElement или FrameworkContentElement для целевого элемента. BindingExpression: Path = HeaderItems [0]; DataItem = NULL; целевым элементом является "DataGridTemplateColumn" (HashCode = 26950454); target является "Заголовок" (тип "Объект" )

Почему отображается эта ошибка?

4b9b3361

Ответ 1

К сожалению, любое DataGridColumn, размещенное под DataGrid.Columns, не является частью дерева Visual и поэтому не связано с контекстом данных в datagrid. Поэтому привязки не работают со своими свойствами, такими как Visibility или Header и т.д. (Хотя эти свойства являются действительными свойствами зависимостей!).

Теперь вы можете удивиться, что это возможно? Не связано ли их свойство Binding с привязкой к контексту данных? Ну это просто хак. Связывание действительно не работает. На самом деле это ячейки datagrid, которые копируют/ клон этот объект привязки и используют его для отображения собственного содержимого!

Итак, теперь, чтобы решить вашу проблему, я предполагаю, что HeaderItems является свойством объекта, который устанавливается как DataContext вашего родительского представления. Мы можем связать DataContext с видом с любым DataGridColumn через то, что мы называем ProxyElement.

В приведенном ниже примере показано, как подключить логический дочерний элемент, такой как ContextMenu или DataGridColumn к родительскому представлению DataContext

 <Window x:Class="WpfApplicationMultiThreading.Window5"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
         xmlns:vb="http://schemas.microsoft.com/wpf/2008/toolkit"
         Title="Window5" Height="300" Width="300" >
  <Grid x:Name="MyGrid">
    <Grid.Resources>
        <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
    </Grid.Resources>
    <Grid.DataContext>
         <TextBlock Text="Text Column Header" Tag="Tag Columne Header"/>
    </Grid.DataContext>
    <ContentControl Visibility="Collapsed"
             Content="{StaticResource ProxyElement}"/>
    <vb:DataGrid AutoGenerateColumns="False" x:Name="MyDataGrid">
        <vb:DataGrid.ItemsSource>
            <x:Array Type="{x:Type TextBlock}">
                <TextBlock Text="1" Tag="1.1"/>
                <TextBlock Text="2" Tag="1.2"/>
                <TextBlock Text="3" Tag="2.1"/>
                <TextBlock Text="4" Tag="2.2"/>
            </x:Array>
        </vb:DataGrid.ItemsSource>
        <vb:DataGrid.Columns>
            <vb:DataGridTextColumn
                       Header="{Binding DataContext.Text,
                                     Source={StaticResource ProxyElement}}"
                       Binding="{Binding Text}"/>
            <vb:DataGridTextColumn
                       Header="{Binding DataContext.Tag,
                                     Source={StaticResource ProxyElement}}"
                       Binding="{Binding Tag}"/>
        </vb:DataGrid.Columns>
    </vb:DataGrid>
  </Grid>
</Window>

В приведенном выше представлении обнаружена та же ошибка привязки, которую вы обнаружили, если я не реализовал хакер ProxyElement. Прокси-элемент - это любой элемент FrameworkElement, который крадет DataContext из основного представления и предлагает его логическому дочернему элементу, например ContextMenu или DataGridColumn. Для этого он должен быть размещен как Content в невидимом ContentControl, который находится под одним и тем же представлением.

Надеюсь, это поможет вам в правильном направлении.