2012-11-19 43 views
1

我的問題似乎很簡單:數據綁定DataGrid自定義列標題

如何將自定義標頭添加到WPF中的數據綁定DataGrid?

我爲什麼問這個問題?那麼,因爲我已將DataGrid(在代碼隱藏中生成)與動態itemssource綁定,並綁定到可枚舉的「列表」。儘管它使用屬性名稱作爲列標題,但它工作得很好。

爲了提高可讀性,我只是想自定義標題分配給列,但是... 我的想法是提供一個已經定義的列的數據網格,並讓itemssource填充行。但是itemssource處理行和列。

我希望你能在這裏看到我的問題。非常感謝幫助!

+0

我們可以看到如何爲您生成的DataGrid? –

回答

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> 

正如你可以看到,一列定義的「標題」屬性將接受任何內容,文字或控件,如果您想進一步自定義它。

編輯

如何從代碼做到這一點的背後,在窗口的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; 
    } 
+0

由於DataGrid是在代碼隱藏中創建的,恐怕我無法訪問XAML ......我必須使用屬性來完成它。 – X3N0N10

+0

你只需要遵循xaml,所以。創建DataGrid對象,將AutoGenerateColumns屬性設置爲false,創建列(有多種類型供您選擇,TextBox,ComboBox,CheckBox等),設置每個列的標題並將它們添加到DataGrid的列採集。不過,您必須爲每個配置綁定,但這很容易。 –

+0

我已經添加了一個如何從後面的代碼中完成它的示例。見編輯的答案。 –

0

如果使用自動生成見鏈接下面

DataGrid.AutoGenerateColumns

或者不自動生成,並建立了具有約束力。
如果這些列是動態的,那麼你必須在後面編碼。
如果列是靜態的,那麼可以使用XAML。

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

如果你知道每次你會得到相同的數據,那麼你可以定義列標題和忘記行。我假設你有相同類型的對象列表,這意味着你將在每一行中顯示相同的屬性。如果你會提供Enumerable的一些例子,情況會很簡單。

您可以在XAML文件中定義列標題,也可以在Columns屬性中定義DataGrid的屬性。

在這之前,您必須將您的列表綁定到Datagrid的itemsource。

1

處理DataGrid的AutoGeneratingColumn事件,然後您可以在默認列名稱(屬性名稱)和自定義標題之間創建某種映射。

例如:

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

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

編輯: taken from MDSN

1

如果您正在從後臺代碼,你可以一個DataGrid指定與DataContextBindings綁定的所有內容。

比方說,我們有一個DataGridmyDataGrid

綁定的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列

// 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值的數據模板

爲您編輯時創建數據模板G顯示了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; 

在DATACELL值添加完成的DataGridColumn到您的DataGrid

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

我知道這是一個很老的帖子,但鮑勃,我有一個問題。 :)我在一個'DataGridTemplateColumn'中有一個'TextBox'和'CheckBox',並且在遵循你的_editing_編碼之後,除非文本框和複選框在我雙擊單元格編輯它之前不可見,否則一切都很完美。有沒有一種方法可以讓這兩個元素始終可見?哦,在我忘記之前!有沒有辦法伸展我的'TextBox'來填充單元格剩餘的剩餘空間? 'textBlockElement.SetValue(TextBlock.Horizo​​ntalAlignmentProperty,Horizo​​ntalAlignment.Stretch);'不起作用 – CareTaker22