<my:DataGridTemplateColumn
CanUserResize = "False"
Width = "150"
Header = "{Binding MeetingName, Source = {StaticResource LocStrings}}"
SortMemberPath = "MeetingName">
</my:DataGridTemplateColumn>
У меня есть столбец выше в элементе управления сеткой Silverlight. Но это дает мне ошибку XamlParser из-за того, как я пытаюсь установить свойство Header. Кто-нибудь делал это раньше? Я хочу сделать это для нескольких языков.
Также мой синтаксис для привязки к ресурсу верен, потому что я пробовал его в ярлыке за пределами сетки.





Вы не можете выполнить привязку к заголовку, потому что это не 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>
Спасибо за ответ. Вы очень помогли.
Это тоже помогло мне. Я смог применить его к DataGridTextColumn практически таким же образом. Я использовал также упомянутое предложение ContentTemplate.
В этом вопросе решение, предоставленное RobSiklos, также сохраняет визуальный стиль.
Я думаю, что принятый ответ должен быть ответом Роба Сиклоса. Не только потому, что сохраняет визуальный стиль, но и потому, что обеспечивает простую реализацию, разделяющую понятия «стиль» и «код».
Почему бы просто не установить это в коде:
dg1.Columns[3].Header = SomeDynamicValue;
У меня есть какое-то решение для привязки. Поскольку вы используете DataGridTemlateColumn, создайте его подкласс и добавьте свойство типа Binding с именем экземпляра «HeaderBinding». Теперь вы можете выполнить привязку к этому свойству из XAML. Затем вы должны распространить привязку на TextBlock в DataTemplate вашего заголовка. Например, вы можете сделать это с помощью события OnLoaded этого TextBlock.
HeaderTextBlock.SetBinding(TextBlock.TextProperty, HeaderBinding);
Вот и все. Если у вас больше столбцов и вы хотите использовать только один DataTemplate, это немного сложнее, но идея та же.
Чтобы сохранить визуальный стиль исходного заголовка, используйте ContentTemplate вместо Template:
<Setter Property = "ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Source = "<image url goes here>"/>
</DataTemplate>
</Setter.Value>
Кажется, не удается получить привязку для работы в DataTemplate на TextBlock: <TextBlock Text = "{Binding HeaderText}" /> заменяет изображение в вашем примере.
По моему опыту, это не помогает сохранить визуальный стиль.
Этот метод определенно подходит, и он ДЕЙСТВИТЕЛЬНО сохраняет визуальный стиль. Если вы повторно шаблонизируете весь заголовок, он станет белым прямоугольником, содержащим все, что вы туда поместили. Однако при использовании ContentTemplate существующий фон стиля заголовка по умолчанию сохраняется.
Кроме того, если вы укажете Источник привязки как некоторый StaticResource (как в исходном сообщении), он будет работать.
Нашел интересный обходной путь, который также работает с wpflocalizeaddin.codeplex.com:
Создано Слый
Он использует 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
Мое обходное решение заключалось в использовании присоединенного свойства для автоматической установки привязки:
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}}" />
В отличие от принятого решения, это решение может делать то же, что и принятое, плюс сохранять исходный стиль. У меня это работает. +1
У меня это тоже работает. Это абсолютно ИДЕАЛЬНО, и то, что я ищу: стиль и код, разделенные как концепции, разделенные в XAML. Большое спасибо, это должно быть приемлемое решение.
Нравится это решение лучше, так как оно сохраняет ответственность и разделение проблем.
Кажется, намного проще установить значение в коде, как упоминалось выше:
dg1.Columns[3].Header = SomeDynamicValue;
Избегает использования синтаксиса Setter Property, который в моем случае, казалось, испортил стиль, хотя я пытался использовать ContentTemplate, а также Template.
Один момент, который я упустил, заключался в том, что лучше использовать
Нотация dg1.Columns[3].Header, а не ссылка на именованный столбец.
Я назвал один из своих столбцов и попытался сослаться на него в коде, но получил нулевые исключения. Метод Columns [index] работал хорошо, и я мог назначить заголовку текстовую строку на основе ресурсов локализации.
Обратите внимание, что в решении, предоставленном RobSiklos, Source {staticResource ...} является ключом, если вы планируете передавать RelativeSource, например
Binding DataContext.SelectedHistoryTypeItem,RelativeSource = {RelativeSource AncestorType=sdk:DataGrid},
это может не сработать
Как сохранить визуальный стиль исходного заголовка?