Настройка автоматически сгенерированных столбцов в элементе управления DataGrid - PullRequest
3 голосов
/ 26 января 2012

Прочитав отличную статью о том, как настроить автоматически сгенерированные столбцы , я столкнулся с проблемой.

Пытаясь настроить автоматически сгенерированные столбцы в элементе управления DataGrid, я хочу сделать простые вещи, например, убедиться, что все числовые значения столбцов выровнены по правому краю. Для этого я создал DataTemplate следующим образом:

<DataGrid x:Name="MyGrid" AutoGeneratingColumn="MyGrid_AutoGeneratingColumn">
  <DataGrid.Resources>
    <DataTemplate x:Key="IntegerTemplate">
      <TextBlock Text="{Binding}" HorizontalAlignment="Right"/>
    </DataTemplate>
  </DataGrid.Resources>
</DataGrid>

Затем в обработчике событий AutoGeneratingColumn DataGrid я хочу назначить этот общий DataTemplate как CellTemplate для всех целых (т. Е. Числовых) столбцов:

public void MyWindow_AdjustColumnTemplateBasedOnType(
              DataGridAutoGeneratingColumnEventArgs e)
{
  if (/*This is a column I want to change*/)
  {
    DataGridTemplateColumn column=new DataGridTemplateColumn(); 

    column.Header=e.PropertyName;
    column.CellTemplate=MyGrid.FindResource("IntegerTemplate") as DataTemplate; 
    e.Column=column; 
  }
}

Проблема в том, что значение столбца Text в TextBlock не отображает желаемых результатов. Вместо того, чтобы видеть правильное обоснованное значение в каждой ячейке, столбец которой имеет DataTemplate в качестве CellTemplate, я вижу:

enter image description here

Использование пустого синтаксиса привязки путем установки атрибута Text в "{Binding}", очевидно, неверно. Установка привязки на основе пути дает желаемый результат. То есть, если я установлю привязку (жестко закодированный путь данных), используя что-то вроде:

  <DataGrid.Resources>
    <DataTemplate x:Key="IntegerTemplate">
      <!-- Binding hard set to ProductId -->
      <TextBlock Text="{Binding ProductId}" HorizontalAlignment="Right"/>
    </DataTemplate>
  </DataGrid.Resources>

Тогда все хорошо, но мой родовой DataTemplate больше не является родовым. Вместо того, чтобы повторно использовать его для всех целочисленных столбцов, его можно использовать только для столбца ProductId, поскольку привязка фиксируется на значении этого конкретного элемента данных:

enter image description here

Какую правильную привязку я должен использовать, чтобы универсальный DataTemplate фактически использовал любое значение в соответствующем свойстве ItemSource для столбца, с которым он связан.

Ответы [ 3 ]

4 голосов
/ 16 апреля 2013

Я считаю, что стили решат вашу проблему здесь.

        private void MyGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {  
            if (/*This is a column I want to change*/)
            {
                DataGridColumn column = e.Column;
                column.CellStyle = MyGrid.FindResource("IntegerTemplate") as Style;

            }
        }

, а в XAML вы можете написать

<Style TargetType="DataGridCell" x:Key="IntegerTemplate">
     <Setter Property="FontWeight" Value="Bold"></Setter>
</Style>    
1 голос
/ 07 июня 2013

Для людей, которые борются с тем, «Какую правильную привязку я должен использовать, чтобы универсальный DataTemplate фактически использовал любое значение в соответствующем свойстве ItemSource для столбца, с которым он связан».

См. Jay_Wang'sответ по этой ссылке:

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8b2e94b7-3c44-4642-8acc-851de5285062

Важный бит переопределяет функцию GenerateElement System.Windows.FrameworkElement, чтобы она могла программно настроить привязку для использования имени столбца.

Надеюсь, это поможет.

0 голосов
/ 27 января 2012

При использовании TemplateColumn в контексте DataGrid вам обычно также необходимо использовать ValueConverter.

Этот ValueConverter преобразует данные из объекта ViewModels (что фактически является причиной, по которой вы хотите использовать TemplateColumвместо обычного TextColumn) в представимую строковую форму.

У вас есть такой преобразователь или вы предоставляете метод ToString () в вашем объекте ViewModels?Если не попробовать, может быть, это поможет ...

...