首页 文章

WPF错误:找不到目标元素的管理FrameworkElement

提问于
浏览
69

我有一个带有图像的Row的数据网格 . 此图像与某个状态的触发器绑定 . 当状态改变时我想改变图像 .

模板本身在DataGridTemplateColumn的HeaderStyle上设置 . 此模板具有一些绑定 . 第一个绑定日显示它是什么日期,状态通过触发器更改图像 .

这些属性在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:路径= HeaderItems [0];的DataItem = NULL; target元素是'DataGridTemplateColumn'(HashCode = 26950454); target属性是'Header'(类型'Object')

为什么会出现此错误?

1 回答

  • 138

    遗憾的是,在 DataGrid.Columns 下托管的任何 DataGridColumn 都不是 Visual 树的一部分,因此没有连接到数据网格的数据上下文 . 因此绑定不能与它们的属性一起使用,例如 VisibilityHeader 等(尽管这些属性是有效的依赖属性!) .

    现在你可能想知道这怎么可能?是不是他们的 Binding 属性应该绑定到数据上下文?嗯它只是一个黑客 . 绑定并不真正起作用 . 它实际上是数据网格单元格 copy / clone 这个绑定对象并用它来显示自己的内容!

    所以现在回到解决你的问题,我假设 HeaderItems 是对象的属性,被设置为父视图的 DataContext . 我们可以通过我们称之为 ProxyElement 的东西将视图的 DataContext 连接到任何 DataGridColumn .

    下面的示例说明了如何将逻辑子项(如 ContextMenuDataGridColumn )连接到父视图的 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 hack,上面的视图遇到了你发现的相同的绑定错误 . ProxyElement是来自主视图的 steals DataContext 的任何FrameworkElement,并将其提供给逻辑子项,例如 ContextMenuDataGridColumn . 为此,它必须作为 Content 托管到同一视图下的不可见 ContentControl 中 .

    我希望这能指导你正确的方向 .

相关问题