2011-10-05 243 views
57

我有一個具有圖像的行的datagrid。該圖像與觸發器綁定到某個狀態。當狀態改變時,我想改變圖像。WPF錯誤:無法找到目標元素的治理FrameworkElement

模板本身設置在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:

<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 Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=HeaderItems[0]; DataItem=null; target element is 'DataGridTemplateColumn' (HashCode=26950454); target property is 'Header' (type 'Object')

爲什麼會顯示此錯誤?

+1

我檢查了上述答案的解決方案,但它不適用於我的情況。當我切換到另一個解決方案,如鏈接http://www.thomaslevesque。COM/2011/03/21/WPF的如何做綁定到數據時,最DataContext的 - 是 - 不繼承/。這個想法與解決方案相同,而不是使用FrameworkElement,他們創建了另一個類。然後它適用於我。 – leo5th

+0

對於通過搜索錯誤消息在這裏結束的其他人:這個類似問題的答案幫助我很容易地解決問題http://stackoverflow.com/a/18657986/4961688 –

回答

118

很遺憾,DataGrid.Columns下的DataGridColumn不是Visual樹的一部分,因此沒有連接到數據網格的數據上下文。因此,綁定不能與其屬性(如VisibilityHeader等)一起使用(儘管這些屬性是有效的依賴項屬性!)。

現在你可能知道怎麼可能?他們的Binding屬性是否應該綁定到數據上下文?那簡直就是黑客。綁定不是真的有效。它實際上是拷貝/克隆這個綁定對象,並用它來顯示自己的內容的數據網格單元!

現在回到解決您的問題,我假設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破解。 ProxyElement是從主視圖中盜取DataContext並將其提供給邏輯孩子(如ContextMenuDataGridColumn)的任何FrameworkElement。爲此,它必須作爲Content託管到不可見的ContentControl之下,這是在相同的視圖下。

我希望這能指導你正確的方向。

+17

我發現必須使用這個hacky代理的東西真的disapointing,但我找不到另一種方式來實現相同的功能,否則...謝謝。 –

+2

這並不適用於我,但在閱讀Josh Smith關於虛擬分支的文章後,我嘗試在我的根控件上添加OneWayToSource綁定來設置「ProxyElement」DataContext,並且工作正常。 – jpierson

+0

@jpierson,你在使用Silverlight嗎?因爲它在'WPF'中適合我。對於silverlight,實現是不同的。 –