WPF DataGrid:调整大小后,ColumnHeaderStyle ContentTemplate 才会以全高显示

发布于 2024-08-13 03:53:51 字数 7539 浏览 3 评论 0原文

这可能是 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 是一个带有 的简单类NameData (字符串)属性。

我观察到,只有 Name 属性ContentTemplateStackPanel 中的第一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光暖心i 2024-08-20 03:53:51

当使用带有 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.

不及他 2024-08-20 03:53:51

如果列是在 Loaded 事件处理程序中创建的,而不是在窗口的构造函数中创建的,则问题将得到解决。

The issue is fixed if the columns are created in the Loaded event handler, rather than in the constructor of the window.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文