数据绑定DataGrid与自定义列标题

时间:2012-11-19 15:19:17

标签: c# wpf binding

我的问题似乎很简单:

如何在WPF中向数据绑定DataGrid添加自定义标头?

为什么我问这个问题?好吧,因为我已经将我的DataGrid(在代码隐藏中生成)与动态itemssource相匹配,绑定到一个不可数的“列表”。虽然它使用属性名称作为列标题,但这种方法完全正常。

为了提高可读性,我只想将自定义标题分配给列,但是...... 我的想法是为数据网格提供已定义的列,并让itemssource填充行。但是itemssource处理行以及列。

我希望你能在这里看到我的问题。非常感谢帮助!

5 个答案:

答案 0 :(得分:1)

处理DataGrid的AutoGeneratingColumn事件,然后您可以在默认列名称(属性名称)和自定义标题之间创建某种映射。

例如:

string headername = e.Column.Header.ToString();

if (headername == "MiddleName")
     e.Column.Header = "Middle Name";

编辑: taken from MDSN

答案 1 :(得分:1)

DataGrid类具有用于配置列生成行为的属性,称为“AutoGenerateColumns”(link)。要禁用此行为,只需将其设置为false。

如果您在xaml中执行此操作,则可以更好地控制DataGrid的形状。一个例子:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow"
    Width="525"
    Height="350">
<Grid>                  
    <DataGrid AutoGenerateColumns="False" >
        <DataGrid.Columns>              
            <DataGridTextColumn Header="MyHeader1" Binding="{Binding MyProperty1}"/>
            <DataGridTextColumn Binding="{Binding MyProperty2}">
                <DataGridTextColumn.Header>
                    <Button Content="A button"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

如您所见,如果您想进一步自定义列定义的“Header”属性,它将接受任何内容,文本或控件。

修改

如何从Window的Loaded事件中的代码中执行此操作的示例:

void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        var dataGrid = new DataGrid();
        dataGrid.AutoGenerateColumns = false;

        // For each column you want
        var column1 = new DataGridTextColumn();
        column1.Header = "MyHeader";
        column1.Binding = new Binding("MyProperty");
        dataGrid.Columns.Add(column1);

        // LayoutRoot is the main grid of the Window
        this.LayoutRoot.Children.Add(dataGrid);


        // Let's test to see if the binding is working
        IEnumerable<DummyClass> testEnumerable = new List<DummyClass>(){
            new DummyClass(){MyProperty= "Element1"},
            new DummyClass(){MyProperty= "Element2"},
        };

        dataGrid.ItemsSource = testEnumerable;
    }

答案 2 :(得分:1)

如果您是从代码隐藏创建DataGrid,则可以指定与DataContextBindings绑定的所有内容。

假设我们有DataGrid myDataGrid

将ItemsSource绑定到myDataGrid

 Binding dataGridItemsSourceBinding = new Binding("MyItemsSourceName");
 myDataGrid.SetBinding(DataGrid.ItemsSourceProperty, datagridItemsSourceBinding);

创建DataGridTemplateColumn

 DataGridTemplateColumn templatecolumn = new DataGridTemplateColumn() {
      Header = "myColumnName", // Add the name of your column here
 };

在DataGrid列的DataCell中显示值时,为数据模板创建

 // Displaying Template for when you display the DataCell in the DataGridColumn
 // Create a Data Template for when you are displaying a DataGridColumn
 DataTemplate textBlockTemplate = new DataTemplate();
 // Create a Framework Element for the DataGridColumn type (In this case, a TextBlock)
 FrameworkElementFactory textBlockElement = new FrameworkElementFactory(typeof(TextBlock));
 // Create a Binding to the value being displayed in the DataGridColumn
 Binding textBlockBinding = new Binding("myPropertyName");
 // Assign the Binding to the Text Property of the TextBlock
 textBlockElement.SetBinding(TextBlock.TextProperty, textBlockBinding);
 // Set the DataGridColumn to stretch to fit the text
 textBlockElement.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
 // Add the TextBlock element to the Visual Tree of the Data Template
 textBlockTemplate.VisualTree = textBlockElement;
 // Add the Data Template to the DataGridColumn Cell Template
 templatecolumn.CellTemplate = textBlockTemplate;

在DataCrid列的DataCell中编辑值时,为数据模板创建

 // Editing Template for when you edit the DataCell in the DataGridColumn
 // Create a Data Template for when you are displaying a DataGridColumn
 DataTemplate textBoxTemplate = new DataTemplate();
 // Create a Framework Element for the DataGrid Column type (In this case, TextBox so the user can type)
 FrameworkElementFactory textBoxElement = new FrameworkElementFactory(typeof(TextBox));
 // Create a Binding to the value being edited in the DataGridColumn
 Binding textBoxBinding = new Binding("myPropertyName");
 // Assign the Binding to the Text Property of the TextBox
 textBoxElement.SetBinding(TextBox.TextProperty, textBoxBinding);
 // Set the DataGridColumn to stretch to fit the text
 textBlockElement.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
 // Add the TextBox element to the Visual Tree of the Data Template
 textBoxTemplate.VisualTree = textBoxElement;
 // Add the Data Template to the DataGridColumn Cell Editing Template
 templatecolumn.CellEditingTemplate = textBoxTemplate;

将完成的DataGridColumn添加到DataGrid

 // Add the completed DataGridColumn to your DataGrid
 myDataGrid.Columns.Add(templateColumn);

答案 3 :(得分:0)

如果使用AutoGenerate,请参阅下面的链接

DataGrid.AutoGenerateColumns

或者不要自动生成并构建绑定 如果列是动态的,那么你必须在后面编码 如果列是静态的,那么可以使用XAML。

<DataGrid Name="DG1" ItemsSource="{Binding}" AutoGenerateColumns="False" >
     <DataGrid.Columns>
          <DataGridTextColumn Header="First Name"  Binding="{Binding FirstName}"/>   

答案 4 :(得分:0)

如果您知道每次获得相同的数据,那么您可以定义列标题并忘记行。我假设你有相同类型的对象列表,这意味着你将在每一行中显示相同的属性。如果您将提供您的Enumerable的一些示例,事情会很简单。

您可以在XAML文件中定义列标题,也可以在列属性中定义DataGrid的属性。

在执行此操作之前,您必须使用Datagrid的itemsource绑定列表。