画像のある行を持つデータグリッドを持っています。このイメージは、特定の状態へのトリガーにバインドされています。状態が変わったら、画像を変更したいです。
テンプレート自体は、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:ターゲット要素の管理FrameworkFrameworkまたはFrameworkContentElementが見つかりません。 BindingExpression:Path = HeaderItems [0]; DataItem = null;ターゲット要素は 'DataGridTemplateColumn'(HashCode = 26950454)です。ターゲットプロパティは 'Header'(タイプ 'Object')です
このエラーが表示されるのはなぜですか?
悲しいことに、DataGrid.Columns
でホストされているDataGridColumn
はVisual
ツリーの一部ではないため、データグリッドのデータコンテキストに接続されていません。したがって、バインディングはVisibility
やHeader
などのプロパティでは機能しません(これらのプロパティは有効な依存関係プロパティです!)。
今、あなたはそれがどのように可能か疑問に思うかもしれません?それらのBinding
プロパティはデータコンテキストにバインドされるはずではありませんか?まあそれは単にハックです。バインディングは実際には機能しません。 copy/cloneこのバインディングオブジェクトは、データグリッドセルであり、独自のコンテンツの表示に使用します!
問題の解決に戻って、HeaderItems
は親ビューのDataContext
として設定されるオブジェクトのプロパティであると仮定します。私たちはcanビューの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は、メインビューのstealsDataContext
であり、ContextMenu
やDataGridColumn
などの論理子に提供するFrameworkElementです。そのため、同じビューの下にある不可視のContent
にContentControl
としてホストする必要があります。
これが正しい方向に導くことを願っています。