[wpf] WPF 오류 : 대상 요소에 대한 관리 FrameworkElement를 찾을 수 없습니다.

내가있어 DataGrid이미지가있는 행과. 이 이미지는 특정 상태에 대한 트리거로 바인딩됩니다. 상태가 변경되면 이미지를 변경하고 싶습니다.

템플릿 자체는 설정되어 HeaderStyleDataGridTemplateColumn. 이 템플릿에는 몇 가지 바인딩이 있습니다. 첫 번째 바인딩 Day는 현재 날짜를 보여주고 State는 트리거로 이미지를 변경합니다.

이러한 속성은 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 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). 대상 속성은 ‘Header'( ‘Object’유형)입니다.

이 오류가 표시되는 이유는 무엇입니까?



답변

슬프게도 DataGridColumn아래에서 호스팅되는 DataGrid.Columns것은 Visual트리의 일부가 아니므로 데이터 그리드의 데이터 컨텍스트에 연결되지 않습니다. 따라서 바인딩은 Visibilityor Header등 의 속성과 함께 작동하지 않습니다 (이 속성은 유효한 종속성 속성이지만!).

이제 그게 어떻게 가능할까요? 그들의 Binding속성이 데이터 컨텍스트에 바인딩되어 있어야 하지 않습니까? 글쎄, 그것은 단순히 해킹입니다. 바인딩이 실제로 작동하지 않습니다. 실제로이 바인딩 개체 를 복사 / 복제 하고 자신의 내용을 표시하는 데 사용하는 것은 데이터 그리드 셀입니다 !

이제 문제를 해결하는 것으로 돌아가서 부모 뷰로 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 해킹을 구현하지 않은 경우 발견 한 것과 동일한 바인딩 오류가 발생했습니다. ProxyElement는 FrameworkElement입니다 훔치는DataContext주요보기와 같은 논리적 아이에게 제안을에서 ContextMenuDataGridColumn. 이를 위해 동일한보기 아래 Content에있는 보이지 않는 것으로 호스팅되어야합니다 ContentControl.

이 정보가 올바른 방향으로 안내되기를 바랍니다.


답변

StaticResource수락 된 답변에서 as 를 사용하는 것보다 약간 짧은 대안 은 x:Reference다음과 같습니다.

<StackPanel>

    <!--Set the DataContext here if you do not want to inherit the parent one-->
    <FrameworkElement x:Name="ProxyElement" Visibility="Collapsed"/>

    <DataGrid>
        <DataGrid.Columns>
            <DataGridTextColumn
                Header="{Binding DataContext.Whatever, Source={x:Reference ProxyElement}}"
                Binding="{Binding ...}" />
        </DataGrid.Columns>
    </DataGrid>

</StackPanel>

이것의 가장 큰 장점은 : 당신이 이미 요소가있는 경우 없는 데이터 그리드의 조상 (즉, 하지StackPanel 위의 예에서), 당신은 그냥 이름을 부여 할 수 있고로 사용할 x:Reference따라서 어떤 더미를 정의하는 데 필요로하지 않는 대신 FrameworkElement조금도.

조상을 참조하려고 XamlParseException하면 순환 종속성으로 인해 런타임에 를 얻을 수 있습니다.


답변