WPF Toolkit DataGrid: how to get ColumnHeader column width equal to GridColumn width

In my WPF Toolkit DataGrid, I use the following column header style:

<Style x:Name="ColumnStyle" x:Key="ColumnHeaderStyle" TargetType="my:DataGridColumnHeader"> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Background="LightYellow"> <TextBlock Text="{Binding Name}" HorizontalAlignment="Stretch" TextAlignment="Left" Background="LightGreen" /> <TextBlock Text="{Binding Data}" HorizontalAlignment="Stretch" TextAlignment="Right" Background="LightBlue" /> </StackPanel> </DataTemplate> </Setter.Value> </Setter> </Style> 

The DataContext header is set in the code, and the properties of the Name and Data row are displayed correctly using the initial width of the DataGrid as follows:

 --------------- |Name | | Data| --------------- 

However, when I resize the column, the header display does not overpay, but remains the same:

 -------------------- |Name | | Data | -------------------- 

where, as I expected, would look like this:

 -------------------- |Name | | Data| -------------------- 

What do I need to do to get the desired behavior above?

Similarly, the contents of the header also do not stretch in the vertical direction.

Update: Addition

  <Setter Property="VerticalAlignment"> <Setter.Value>Bottom</Setter.Value> </Setter> 

for the style, it seems to correctly align the title from the bottom. Unfortunately, setting the HorizontalAlignment property in the "Stretch" method does not seem to do what I'm looking for.

Details for Repro: The following are code snippets showing behavior.

Window1.xaml:

 <Window x:Class="GridTest.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit"> <Window.Resources> <Style x:Name="ColumnStyle" x:Key="ColumnHeaderStyle" TargetType="my:DataGridColumnHeader"> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <DockPanel> <TextBlock DockPanel.Dock="Left" Text="{Binding Name}" /> <TextBlock DockPanel.Dock="Right" Text="{Binding Data}" /> </DockPanel> </DataTemplate> </Setter.Value> </Setter> </Style> <Style x:Name="RowHeaderStyle" x:Key="RowHeaderStyle" TargetType="my:DataGridRowHeader"> <Setter Property="Content" Value="{Binding}" /> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Content.Name, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type my:DataGridRowHeader}}}" VerticalAlignment="Center"/> <TextBlock Padding="5">|</TextBlock> <TextBlock Text="{Binding Path=Content.Data, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type my:DataGridRowHeader}}}" VerticalAlignment="Center"/> </StackPanel> </DataTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <my:DataGrid Name="dg" ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}" RowHeaderStyle="{StaticResource RowHeaderStyle}" HeadersVisibility="All"> </my:DataGrid> </Grid> </Window> 

and code in Window1.xaml.cs

 using System; using System.Collections.Generic; using System.Windows; using System.Windows.Data; using Microsoft.Windows.Controls; using SLModel; namespace GridTest { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); this.Loaded += new RoutedEventHandler(Window1_Loaded); } void Window1_Loaded(object sender, RoutedEventArgs e) { Inputs = new List<Input>(); Outputs = new List<Output>(); Input i1 = new Input() { Name = "I 1", Data = "data 1" }; Input i2 = new Input() { Name = "I 2", Data = "data 2" }; Input i3 = new Input() { Name = "I 3", Data = "data 3" }; Inputs.Add(i1); Inputs.Add(i2); Output o1 = new Output() { Name = "O 1", Data = "data 1" }; Output o2 = new Output() { Name = "O 2", Data = "data 2" }; Output o3 = new Output() { Name = "O 3", Data = "data 3" }; Outputs.Add(o1); Outputs.Add(o2); Outputs.Add(o3); Relationship r1 = new Relationship() { Formula = "F1" }; Relationship r2 = new Relationship() { Formula = "F2" }; Relationship r3 = new Relationship() { Formula = "F3" }; Relationship r4 = new Relationship() { Formula = "F4" }; Relationship r5 = new Relationship() { Formula = "F5" }; Relationship r6 = new Relationship() { Formula = "F6" }; i1.Relationships.Add(r1); i1.Relationships.Add(r2); i2.Relationships.Add(r3); i2.Relationships.Add(r4); i3.Relationships.Add(r5); i3.Relationships.Add(r6); CreateColumn(o1, 0); CreateColumn(o2, 1); CreateColumn(o3, 2); dg.Items.Add(i1); dg.Items.Add(i2); dg.Items.Add(i3); dg.ColumnWidth = DataGridLength.SizeToHeader; } private void CreateColumn(Output output, int index) { Binding textBinding = new Binding(); textBinding.Path = new PropertyPath(string.Format("Relationships[{0}].Formula", index)); textBinding.Mode = BindingMode.TwoWay; DataGridTextColumn tc = new DataGridTextColumn(); tc.Binding = textBinding; dg.Columns.Add(tc); tc.Header = output; } private List<Output> Outputs { get; set; } private List<Input> Inputs { get; set; } } } 

With simple classes Input, Output and Relationship as such:

public input class {public Input () {Relations = new ObservableCollection (); }

 public string Name { get; set; } public string Data { get; set; } public ObservableCollection<Relationship> Relationships { get; set; } 

}

open class. {public Output () {}

 public string Name { get; set; } public string Data { get; set; } 

}

public class Relationships {public relations () {} public string Formula {get; set; }}

Repro steps:

  • Launch the application

  • Observe the column headings "O 1data 1", "O 2data 2" and "O 3data 3"

  • Make the first column wider by dragging the column separator to the right

  • Please note that the distance between the "TextBlock" (in this case "O 1") and the "Data" TextBlock ("data 1") does not change, i.e. "Data" TextBlock is not "docked" to the right of the column header.

+4
source share
3 answers

I suggest replacing the StackPanel with a Grid :

 <Style x:Name="ColumnStyle" x:Key="ColumnHeaderStyle" TargetType="my:DataGridColumnHeader"> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Name}" Background="LightGreen" /> <TextBlock Grid.Row="1" Grid.Column="2" Text="{Binding Data}" Background="LightBlue" /> </Grid> </DataTemplate> </Setter.Value> </Setter> </Style> 

If this does not work, you may need to edit the ControlTemplate for the DataGridColumnHeader . I'm not sure what the default template looks like, but if ContentPresenter not inside a stretchable container (e.g. Grid ), it doesn't matter if you stretch inside ContentPresenter , it won Not Stretch. But one thing I'm pretty sure about is that StackPanels don't stretch even if you tell them, so first try the Grid in your DataTemplate .

Update (fixed)

Ok, I dug out the default ControlTemplate for the DataGridColumnHeader . It turns out if Grid using, so I don't think this is a problem.

The key may be ContentPresenter :

 <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" /> 

You may need to set HorizontalContentAlignment="Stretch" to your DataGridColumnHeader style.

+4
source

Using WPF 4 DataGrid, but had the same problem and just set the HorizontalContentAlignment in the style of the DataGridColumnHeader, solved this for me (DanM loan, which suggested it above) ...

 <Style TargetType="{x:Type DataGridColumnHeader}"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> </Style> 
+3
source

Use the dock panel instead

 <DockPanel Background="LightYellow"> <TextBlock DockPanel.Dock="Left" Text="{Binding Name}" TextAlignment="Left" Background="LightGreen" /> <TextBlock DockPanel.Dock="Right" Text="{Binding Data}" HorizontalAlignment="Right" TextAlignment="Right" Background="LightBlue" /> </DockPanel > 
0
source

Source: https://habr.com/ru/post/1299488/


All Articles