1

我的问题似乎很简单:

如何将自定义标题添加到 WPF 中的数据绑定 DataGrid?

我为什么要问这个问题?好吧,因为我已经为我的 DataGrid(在代码隐藏中生成)安装了一个动态项目源,绑定到一个可枚举的“列表”。尽管它使用属性名称作为列标题,但它工作得非常好。

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

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

4

5 回答 5

1

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

例如:

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

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

编辑: 取自MDSN

于 2012-11-19T15:41:27.987 回答
1

DataGrid 类有一个属性来配置列生成行为,称为“AutoGenerateColumns”(链接)。要禁用此行为,只需将其设置为 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>

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

编辑

在 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;
    }
于 2012-11-19T15:49:48.527 回答
1

如果您从代码隐藏创建 DataGrid,则可以指定您使用DataContext和绑定的所有内容Bindings

假设我们有一个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
 };

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

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

当您在 DataCell 中为 DataGrid 列编辑值时创建数据模板

 // 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);
于 2012-11-19T15:59:18.060 回答
0

如果使用自动生成,请参见下面的链接

DataGrid.AutoGenerateColumns

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

<DataGrid Name="DG1" ItemsSource="{Binding}" AutoGenerateColumns="False" >
     <DataGrid.Columns>
          <DataGridTextColumn Header="First Name"  Binding="{Binding FirstName}"/>   
于 2012-11-19T15:35:08.587 回答
0

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

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

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

于 2012-11-19T15:37:58.690 回答