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


87

내가있어 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'유형)입니다.

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


4
위의 답변 된 솔루션을 확인했지만 제 경우에는 작동하지 않습니다. 링크 thomaslevesque.com/2011/03/21/… 에서와 같이 다른 솔루션으로 전환 할 때 . 아이디어는 솔루션과 동일하며 FrameworkElement를 사용하는 대신 다른 클래스를 만들었습니다. 그렇다면 그것은 나를 위해 작동합니다.
leo5th

다른 오류 메시지를 검색하여 여기에 끝나는 경우 :이 비슷한 질문의 대답은 비교적 쉽게 문제를 해결하기 위해 나를 도와 stackoverflow.com/a/18657986/4961688
팀 Pohlmann

답변:


165

슬프게도 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.

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


25
이 해키 프록시를 사용해야하는 것은 정말 실망 스럽지만 동일한 기능을 달성하는 다른 방법을 찾을 수 없습니다. 감사합니다.
Alex Hope O'Connor

2
이것은 나를 위해 작동하지 않았지만 가상 분기에 대한 Josh Smith의 기사를 읽은 후 루트 컨트롤에 OneWayToSource 바인딩을 추가하여 "ProxyElement"DataContext를 설정하려고 시도했으며 작동했습니다.
jpierson 2012

1
아니. 위의 솔루션은 .NET 3.5에 매우 적합합니다.
WPF-it

1
이 답변은 오래되었지만 .NET 4.0에 여전히 유용합니다. DataContext를 열에 복사하는 것과 관련된 많은 답변이 작동하지 않는 것 같습니다. 뷰 모델 속성에 따라 열을 표시하거나 숨겨야했는데이 솔루션이 잘 작동했습니다. 그리고 코드가 없으면 코드 검토에서 외교적 사고가 발생하지 않습니다.
James_UK_DEV

3
참고로 컨텍스트 메뉴는 동일하지 않으며 비 프록시 해결 방법이 있습니다. 상황에 맞는 메뉴에는 노출 된 속성이 Parent있지만는 속성을 DataGridTextColumn노출하지 않습니다 DataGridOwner. 상황에 맞는 항목 RelativeSource 내 대답에 바인딩을 통해 수행 바인딩하는 방법을 참조하십시오 부모 윈도우의 데이터 컨텍스트에 바인딩 컨텍스트 메뉴
ΩmegaMan

8

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하면 순환 종속성으로 인해 런타임에 를 얻을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.