Michael Goldshteyn
Michael Goldshteyn

Reputation: 74360

Customizing Auto-Generated Columns in the DataGrid Control

After reading the excellent article on how to Customize Auto-Generated Columns, I have come across an issue.

While trying to customize auto-generated columns in a DataGrid control, I want to do simple things like make sure that all numeric column values are right-aligned. To this end, I created a DataTemplate as follows:

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

Then, in the AutoGeneratingColumn DataGrid event handler, I want to assign this generic DataTemplate as the CellTemplate for all integral (i.e., numeric) columns:

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; 
  }
}

The problem is that the value of the Text column of the TextBlock does not display the desired results. Instead of seeing the right justified value in each cell whose column has this DataTemplate as its CellTemplate, I see:

enter image description here

Using the empty binding syntax by setting the attribute Text to "{Binding}" is obviously incorrect. Setting a path based binding does produce the desired result. That is, if I set a (hard-coded data path) binding using something like:

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

Then all is well, but my generic DataTemplate is no longer generic. Instead of it being reusable for all integer columns, it can only be used for the ProductId column, because the binding is fixed to the value of that specific data item:

enter image description here

What is the correct binding I should use so that the generic DataTemplate actually uses whatever value is in the corresponding ItemSource property for the column with which it is associated.

Upvotes: 4

Views: 9097

Answers (3)

Mukwasha
Mukwasha

Reputation: 11

For people struggling with the "What is the correct binding I should use so that the generic DataTemplate actually uses whatever value is in the corresponding ItemSource property for the column with which it is associated."

See Jay_Wang's answer in this link:

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

The important bit is overriding the System.Windows.FrameworkElement GenerateElement function so that it can programatically set up the binding to use the column name.

Hope this helps.

Upvotes: 1

user2286346
user2286346

Reputation: 61

I believe styles will solve your issue here .

        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;

            }
        }

and in XAML you can write

<Style TargetType="DataGridCell" x:Key="IntegerTemplate">
     <Setter Property="FontWeight" Value="Bold"></Setter>
</Style>    

Upvotes: 6

marc wellman
marc wellman

Reputation: 5886

When using a TemplateColumn in a DataGrid context you usually have to use a ValueConverter as well.

This ValueConverter converts the data from you ViewModels object (which is in fact the reason why you want to use a TemplateColum instead of an ordinary TextColumn) to an representable string form.

Do you have such a converter or do you provide a ToString() method in your ViewModels object ? If not try it, maybe that helps ...

Upvotes: 1

Related Questions