I am trying to make a datagrid with a custom header that has a textblock and a button. The textblock and button is represented by this UserControl
I created:
<UserControl x:Class="SilverlightWorkshop.Controls.CollapsibleDataGridHeader"
...
/>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding HeaderText, Mode=TwoWay}" />
<Button Content="←" Click="ArrowButtonClick"/>
</StackPanel>
</UserControl>
The idea is, when the user clicks the button, the column width will collapse to a small size. However, I am having trouble finding an elegant solution for using this control as a template for a column header.
This works:
<sdk:DataGrid>
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn>
<sdk:DataGridTextColumn.Header>
foo
</sdk:DataGridTextColumn.Header>
</sdk:DataGridTextColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
But I can't drop in a control. This does not work:
<sdk:DataGrid>
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn>
<sdk:DataGridTextColumn.Header>
<Button/>
</sdk:DataGridTextColumn.Header>
</sdk:DataGridTextColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
However, http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.datagridcolumnheader(v=vs.95).aspx implies that I could add a single object as a child of the header.
The closest I've gotten is setting the header as a style:
<navigation:Page xmlns:my="clr-namespace:SilverlightWorkshop.Controls" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightWorkshop.Views.CollapsibleColumns"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="640" d:DesignHeight="480"
Title="CollapsibleColumns Page">
<navigation:Page.Resources>
<Style x:Key="CollapsibleHeaderStyle" TargetType="sdk:DataGridColumnHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="sdk:DataGridColumnHeader">
<my:CollapsibleDataGridHeader HeaderText="Cheese" ArrowButtonClicked="ArrowButtonClick"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</navigation:Page.Resources>
<sdk:DataGrid ItemsSource="{Binding Data, Mode=TwoWay}" AutoGenerateColumns="False">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding String2, Mode=TwoWay}" HeaderStyle="{StaticResource CollapsibleHeaderStyle}"/>
<sdk:DataGridTextColumn Binding="{Binding String1, Mode=TwoWay}"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</navigation:Page>
However, there are a couple things that I do not like. Setting the template property of the column header wipes out some of the default appearance, like the background color of the header and the sort icon. It looks like I literally replace the whole thing.
Also, I'm not sure how I can find out which column header was clicked so I can change the width of the appropriate column nor how I would bind different header names for each column to the HeaderText
property in my CollapsibleDataGridHeader
control.
Is it possible to avoid using styles and instead assign my control to the column header? If not, how would I go do bindings and retrieve which column was clicked using the Style-setting solution above?
This post by Manas Patnaik seems to have the answer:
There is XAML displaying how to set the header template so it retains the default style, and also an explanation of how to access the controls from the DataGrid header through code-behind.
This answer explains how to bind to the controls set in the Style:
Dynamically setting the Header text of a Silverlight DataGrid Column
来源:https://stackoverflow.com/questions/11145092/how-can-i-assign-a-custom-usercontrol-to-a-datagrid-column-header