2010-01-26 60 views
4

对于我的WPF工具包的DataGrid我用下面的自定义列标题样式:WPF工具包的DataGrid:如何获得ColumnHeader宽度是相同的GridColumn宽度

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

头的DataContext的是代码和名称设置和数据串属性显示使用正确的数据网格的这样的初始宽度:

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

然而,当我调整列,标题显示不回流,而是保持相同:

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

在那里,我也希望看起来像这样:

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

什么我需要做的就是上述所需的行为?

类似地,标题内容似乎也不在垂直方向拉伸。

更新: 添加

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

的风格似乎正确对齐头底部。不幸的是,将Horizo​​ntalAlignment属性设置为'Stretch'似乎不符合我的要求。

Repro的详细信息: 下面是说明行为的代码片段。

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> 

和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; } 
    } 
} 

随着简单的类输入,输出,和关系为这样:

公共类输入 { 公共输入() { 关系=新的ObservableCollection(); }

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

public ObservableCollection<Relationship> Relationships { get; set; } 

}

公共类输出 { 公共输出(){}

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

}

公共类关系 { 公共关系(){} public string Formula {get;组; } }

摄制步骤:

  1. 启动应用程序

  2. 观察列标题 'O 1数据1', 'O 2数据2',和 'O 3data 3'

  3. 通过将列分隔符向右拖动,使第一列变宽

  4. 观察到'Name'TextBlock(在这种情况下为'O 1')和'Data'TextBlock('data 1')没有改变,即'Data'TextBlock没有'停靠'到列标题的右边缘。

回答

4

我建议免去您StackPanelGrid

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

如果不工作,你可能需要编辑ControlTemplateDataGridColumnHeader。我不确定默认模板的外观如何,但如果ContentPresenter未位于可伸缩容器(如Grid)内,则如果展开ContentPresenter内部的内容,则无法伸展。但有一件事我很确定,即使你告诉他们,StackPanels也不会伸展,所以一定要先在DataTemplate之前尝试Grid

更新(固定)

好吧,我挖出了默认ControlTemplateDataGridColumnHeader。原来是确实使用了一个Grid,所以我没有认为这就是问题所在。

的关键可能是ContentPresenter

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

你可能只需要设置HorizontalContentAlignment="Stretch"DataGridColumnHeader风格。

+0

@Phillip,我想你还需要更改'ControlTemplate'。请参阅我的答案更新。 – devuxer 2010-01-28 02:11:10

+0

它看起来像是为行标题抓取了控件模板。我会找到一个列标题,并使用您的指示将验证我认为是正确的解决方案。 为什么扩展面板不是我默认的默认值? – 2010-01-28 05:21:12

+0

哦,你说得对。对不起,关于它。它看起来像列标题使用一个网格,而不是一个StackPanel。请参阅我的最新更新。 – devuxer 2010-01-28 06:25:41

0

使用底座面板代替

<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

似乎这不是让任何差异。我已经为每个元素添加了DockPanel.Dock =“Top”,但是当列的大小超出初始大小时,它们仍然不会跨越整个列的宽度。 是否有一些其他属性需要设置才能正确展开? – 2010-01-27 04:14:16

+0

抱歉遗漏了DockPanel.Dock =“Left”和“Right”,相应地编辑过的文章 – 2010-01-27 05:04:14

+0

在我的实际示例中,实际上有4个项目是垂直堆叠的,所以我设置了DockPanel.Dock =“Top”他们。但是这并没有让他们横向扩张。 – 2010-01-27 06:32:32

3

使用WPF 4 DataGrid中,但有同样的问题,只是在DataGridColumnHeader风格设置Horizo​​ntalContentAlignment解决了这个问题对我来说(信用DanM谁建议上面)...

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