WPF DataGrid:调整大小后,ColumnHeaderStyle ContentTemplate 才会以全高显示
这可能是 WPF 工具包 DataGrid
中的错误。
在我的 Windows.Resources 中,我定义了以下 ColumnHeaderStyle
:
<Style x:Name="ColumnStyle" x:Key="ColumnHeaderStyle" TargetType="my:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Data}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
因为我的列是动态生成的,所以我在代码中定义列:
private void CreateColumn(Output output, int index)
{
Binding textBinding = new Binding(string.Format("Relationships[{0}].Formula", index));
DataGridTextColumn tc = new DataGridTextColumn();
tc.Binding = textBinding;
dg.Columns.Add(tc);
tc.Header = output;
}
其中 Output
是一个带有 的简单类Name
和 Data
(字符串)属性。
我观察到,只有 Name 属性(ContentTemplate
的 StackPanel
中的第一个 TextBlock
控件)显示。当我拖动这些列标题之一时,我会看到整个标题(包括数据 TextBlock
)。只有手动调整其中一列的大小后,列标题才会正确呈现。有没有办法让列标题在代码中正确显示?
更新:根据要求,这是我的复制代码的其余部分。
public class Input
{
public Input()
{
Relationships = new ObservableCollection<Relationship>();
}
public string Name { get; set; }
public string Data { get; set; }
public ObservableCollection<Relationship> Relationships { get; set; }
}
public class Output
{
public Output() { }
public string Name { get; set; }
public string Data { get; set; }
}
public class Relationship
{
public Relationship() { }
public string Formula { get; set; }
}
这是 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>
<SolidColorBrush x:Key="RowHeaderIsMouseOverBrush" Color="Red" />
<SolidColorBrush x:Key="RowBackgroundSelectedBrush" Color="Yellow" />
<BooleanToVisibilityConverter x:Key="bool2VisibilityConverter" />
<Style x:Key="RowHeaderGripperStyle" TargetType="{x:Type Thumb}">
<Setter Property="Height" Value="2"/>
<Setter Property="Background" Value="Green"/>
<Setter Property="Cursor" Value="SizeNS"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Name="ColumnStyle" x:Key="ColumnHeaderStyle" TargetType="my:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Data}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- from http://www.codeplex.com/wpf/WorkItem/View.aspx?WorkItemId=9193 -->
<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>
<DataTemplate x:Key="CellTemplate">
<StackPanel>
<TextBox Text="{Binding Formula, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="CellEditTemplate">
<StackPanel>
<TextBox Text="{Binding Formula, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<my:DataGrid Name="dg"
ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}"
RowHeaderStyle="{StaticResource RowHeaderStyle}"
HeadersVisibility="All" />
</Grid>
</Window>
最后是隐藏代码:
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
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" };
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" };
i1.Relationships.Add(r1);
i1.Relationships.Add(r2);
i2.Relationships.Add(r3);
i2.Relationships.Add(r4);
CreateColumn(o1, 0);
CreateColumn(o2, 1);
CreateColumn(o3, 2);
dg.Items.Add(i1);
dg.Items.Add(i2);
dg.ColumnWidth = DataGridLength.SizeToHeader;
}
private void CreateColumn(Output output, int index)
{
Binding textBinding = new Binding(string.Format("Relationships[{0}].Formula", index));
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; }
}
This might be a bug in the WPF Toolkit DataGrid
.
In my Windows.Resources I define the following ColumnHeaderStyle
:
<Style x:Name="ColumnStyle" x:Key="ColumnHeaderStyle" TargetType="my:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Data}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Because my columns are generated dynamically, I am defining the columns in code:
private void CreateColumn(Output output, int index)
{
Binding textBinding = new Binding(string.Format("Relationships[{0}].Formula", index));
DataGridTextColumn tc = new DataGridTextColumn();
tc.Binding = textBinding;
dg.Columns.Add(tc);
tc.Header = output;
}
where Output
is a simple class with Name
and Data
(string) properties.
What I observe is that only the Name property (first TextBlock
control in the ContentTemplate
's StackPanel
) is shown. When I drag one of these column headers, I see the entire header (including the Data TextBlock
). Only after manually resizing one of the columns are the column headers rendered correctly. Is there a way to get the column headers to show up correctly in code?
Update: as requested, here is the rest of my code for the repro.
public class Input
{
public Input()
{
Relationships = new ObservableCollection<Relationship>();
}
public string Name { get; set; }
public string Data { get; set; }
public ObservableCollection<Relationship> Relationships { get; set; }
}
public class Output
{
public Output() { }
public string Name { get; set; }
public string Data { get; set; }
}
public class Relationship
{
public Relationship() { }
public string Formula { get; set; }
}
Here is the XAML markup:
<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>
<SolidColorBrush x:Key="RowHeaderIsMouseOverBrush" Color="Red" />
<SolidColorBrush x:Key="RowBackgroundSelectedBrush" Color="Yellow" />
<BooleanToVisibilityConverter x:Key="bool2VisibilityConverter" />
<Style x:Key="RowHeaderGripperStyle" TargetType="{x:Type Thumb}">
<Setter Property="Height" Value="2"/>
<Setter Property="Background" Value="Green"/>
<Setter Property="Cursor" Value="SizeNS"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Name="ColumnStyle" x:Key="ColumnHeaderStyle" TargetType="my:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Data}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- from http://www.codeplex.com/wpf/WorkItem/View.aspx?WorkItemId=9193 -->
<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>
<DataTemplate x:Key="CellTemplate">
<StackPanel>
<TextBox Text="{Binding Formula, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="CellEditTemplate">
<StackPanel>
<TextBox Text="{Binding Formula, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<my:DataGrid Name="dg"
ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}"
RowHeaderStyle="{StaticResource RowHeaderStyle}"
HeadersVisibility="All" />
</Grid>
</Window>
And finally the code-behind:
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
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" };
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" };
i1.Relationships.Add(r1);
i1.Relationships.Add(r2);
i2.Relationships.Add(r3);
i2.Relationships.Add(r4);
CreateColumn(o1, 0);
CreateColumn(o2, 1);
CreateColumn(o3, 2);
dg.Items.Add(i1);
dg.Items.Add(i2);
dg.ColumnWidth = DataGridLength.SizeToHeader;
}
private void CreateColumn(Output output, int index)
{
Binding textBinding = new Binding(string.Format("Relationships[{0}].Formula", index));
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; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当使用带有 ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}" 的简单 DataGrid 并使用 CreateColumn 方法添加列时,我无法复制此内容:两个 TextBlock 立即显示正常(在两条单独的行上)。
您能否粘贴完整的 DataGrid 声明以及它可能使用的任何其他样式?
另外,您使用的 wpftoolkit 版本是什么?我使用 6 月版本和 .NET 4 Beta 2 中包含的 DataGrid 进行了测试。
When using a simple DataGrid with ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}", and adding columns using your CreateColumn method, I'm not able to replicate this: both TextBlocks show up fine (on two separate lines) right away.
Could you paste your full DataGrid declaration, and any other styles you have that it might be using?
Also, what version of wpftoolkit are you using? I tested both with the June release and with the DataGrid included in .NET 4 Beta 2.
如果列是在 Loaded 事件处理程序中创建的,而不是在窗口的构造函数中创建的,则问题将得到解决。
The issue is fixed if the columns are created in the Loaded event handler, rather than in the constructor of the window.