2010-01-26 81 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>