<my:DataGridTemplateColumn
CanUserResize="False"
Width="150"
Header="{Binding MeetingName, Source={StaticResource LocStrings}}"
SortMemberPath="MeetingName">
</my:DataGridTemplateColumn>
上記の列がSilverlightグリッドコントロールにあります。しかし、Headerプロパティを設定しようとしているため、XamlParserエラーが発生します。誰かが以前にこれをしたことがありますか?複数の言語でこれを実行したいと思います。
また、グリッドの外側のラベルで試したため、リソースへのバインドの構文は正しいです。
FrameworkElementではないため、ヘッダーにバインドすることはできません。次のようにヘッダーテンプレートを変更することで、テキストを動的にすることができます。
xmlns:data="clr-namespace:System.Windows.Controls;Assembly=System.Windows.Controls.Data"
xmlns:dataprimitives="clr-namespace:System.Windows.Controls.Primitives;Assembly=System.Windows.Controls.Data"
<data:DataGridTemplateColumn>
<data:DataGridTemplateColumn.HeaderStyle>
<Style TargetType="dataprimitives:DataGridColumnHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Text="{Binding MeetingName, Source={StaticResource LocStrings}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</data:DataGridTemplateColumn.HeaderStyle>
</data:DataGridTemplateColumn>
私の回避策は、添付プロパティを使用してバインディングを自動的に設定することでした。
public static class DataGridColumnHelper
{
public static readonly DependencyProperty HeaderBindingProperty = DependencyProperty.RegisterAttached(
"HeaderBinding",
typeof(object),
typeof(DataGridColumnHelper),
new PropertyMetadata(null, DataGridColumnHelper.HeaderBinding_PropertyChanged));
public static object GetHeaderBinding(DependencyObject source)
{
return (object)source.GetValue(DataGridColumnHelper.HeaderBindingProperty);
}
public static void SetHeaderBinding(DependencyObject target, object value)
{
target.SetValue(DataGridColumnHelper.HeaderBindingProperty, value);
}
private static void HeaderBinding_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DataGridColumn column = d as DataGridColumn;
if (column == null) { return; }
column.Header = e.NewValue;
}
}
次に、XAMLで:
<data:DataGridTextColumn util:DataGridColumnHelper.HeaderBinding="{Binding MeetingName, Source={StaticResource LocStrings}}" />
元のヘッダーの視覚的なスタイルを維持するには、テンプレートの代わりにContentTemplateを使用します。
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Source="<image url goes here>"/>
</DataTemplate>
</Setter.Value>
上記のように、コードで値を設定する方がはるかに簡単なようです。
dg1.Columns[3].Header = SomeDynamicValue;
TemplateだけでなくContentTemplateも使用しようとしたにもかかわらず、私の場合はスタイルを台無しにしているように見えるSetterProperty構文の使用を避けます。
私が気づかなかった1つのポイントは、名前付きの列を参照するよりも、dg1.Columns[3].Header
表記を使用する方がよいということでした。
列の1つに名前を付け、コードでそれを参照しようとしましたが、null例外が発生しました。 Columns [index]メソッドを使用するとうまく機能し、ローカリゼーションリソースに基づいてヘッダーにテキスト文字列を割り当てることができました。
wpflocalizeaddin.codeplex.com でも機能する興味深い回避策が見つかりました:
作成者 Slyi
IValueConverter
を使用します:
public class BindingConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value.GetType().Name == "Binding")
{
ContentControl cc = new ContentControl();
cc.SetBinding(ContentControl.ContentProperty, value as Binding);
return cc;
}
else return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
そしてDataGridColumnHeader
のスタイル
<UserControl.Resources>
<local:BindingConverter x:Key="BindCon"/>
<Style x:Key="ColBinding" TargetType="dataprimitives:DataGridColumnHeader" >
<Setter Property="ContentTemplate" >
<Setter.Value>
<DataTemplate>
<ContentPresenter Content="{Binding Converter={StaticResource BindCon}}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
Header
属性にお気に入りのバインディング構文を保持できるようにします
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<TextBox Text="binding header" x:Name="tbox" />
<data:DataGrid ItemsSource="{Binding AllPeople,Source={StaticResource folks}}" AutoGenerateColumns="False" ColumnHeaderStyle="{StaticResource ColBinding}" >
<data:DataGrid.Columns>
<data:DataGridTextColumn Binding="{Binding ID}"
Header="{Binding Text, ElementName=tbox}" />
<data:DataGridTextColumn Binding="{Binding Name}"
Header="hello" />
</data:DataGrid.Columns>
</data:DataGrid>
</StackPanel>
</Grid>
http://cid-289eaf995528b9fd.skydrive.live.com/self.aspx/Public/HeaderBinding.Zip
これをコードで単純に設定してみませんか?
dg1.Columns[3].Header = SomeDynamicValue;
RobSiklosが提供するソリューションでは、RelativeSourceを次のように渡す場合は、ソース{staticResource ...}がキーであることに注意してください。
Binding DataContext.SelectedHistoryTypeItem,RelativeSource={RelativeSource AncestorType=sdk:DataGrid},
動作しない可能性があります
バインディングの解決策がありました。 DataGridTemlateColumnを使用するため、サブクラス化して、たとえば「HeaderBinding」という名前のBindingタイプのプロパティを追加します。これで、XAMLからそのプロパティにバインドできます。次に、ヘッダーのDataTemplateでTextBlockへのバインディングを伝播する必要があります。たとえば、そのTextBlockのOnLoadedイベントでそれを行うことができます。
HeaderTextBlock.SetBinding(TextBlock.TextProperty, HeaderBinding);
それでおしまい。より多くの列があり、1つのDataTemplateのみを使用する場合は、少し複雑になりますが、考え方は同じです。