WPF Toolkit DataGrid: как получить ширину ColumnHeader, равную ширине GridColumn - PullRequest
4 голосов
/ 27 января 2010

Для моей таблицы данных WPF Toolkit я использую следующий пользовательский стиль заголовка столбца:

<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 отображаются правильно, используя начальную ширину DataGrid, например:

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

Однако, когда я изменяю размер столбца, отображение заголовка не переформатируется, а остается неизменным:

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

где, как я ожидал, это будет выглядеть так:

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

Что мне нужно сделать, чтобы получить желаемое поведение выше?

Аналогично, содержимое заголовка также не растягивается в вертикальном направлении.

Обновление: Добавление

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

для стиля, кажется, правильно выровнять заголовок к нижней части. К сожалению, установка свойства HorizontalAlignment в моде на 'Stretch', кажется, не делает то, что я ищу.

Подробности для воспроизведения: Ниже приведены фрагменты кода, демонстрирующие поведение.

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

С простыми классами Input, Output и Relationship как таковыми:

Публичный класс Input { публичный ввод () { Relationships = new ObservableCollection (); }

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

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

}

открытый класс { public Output () {}

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

}

публичный класс Отношения { публичные отношения() { } открытая строка Formula {get; задавать; } }

Репро шаги:

  1. Запустить приложение

  2. Обратите внимание на заголовки столбцов 'O 1data 1', 'O 2data 2' и 'O 3data 3'

  3. Увеличьте ширину первого столбца, перетащив разделитель столбцов вправо

  4. Обратите внимание, что расстояние между текстовым блоком «Имя» (в данном случае «O 1») и текстовым блоком «Данные» («данные 1») не меняется, т. Е. Текстовый блок «Данные» не изменяется «пристыкован» к правому краю заголовка столбца.

Ответы [ 3 ]

4 голосов
/ 28 января 2010

Я предлагаю заменить StackPanel на 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>

Если это не сработает, вам может понадобиться отредактировать ControlTemplate для DataGridColumnHeader. Я не уверен, как выглядит шаблон по умолчанию, но если ContentPresenter не находится внутри растягиваемого контейнера (например, Grid), не имеет значения, растянете ли вы то, что находится внутри ContentPresenter, он выиграет не тянется Но одна вещь, в которой я почти уверен: StackPanels не растягивайте, даже если вы скажете им это, так что обязательно попробуйте Grid в вашем DataTemplate сначала.

Обновление (исправлено)

Хорошо, я выкопал значение по умолчанию ControlTemplate для DataGridColumnHeader. Оказывается, использует Grid, поэтому я не думаю, в этом проблема.

Ключ может быть ContentPresenter:

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

Возможно, вам просто нужно установить HorizontalContentAlignment="Stretch" в вашем стиле DataGridColumnHeader.

3 голосов
/ 03 апреля 2011

Использование WPF 4 DataGrid, но возникла та же проблема, и простая настройка HorizontalContentAlignment в стиле DataGridColumnHeader решила ее для меня (благодарность DanM, предложившему это выше) ...

<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
0 голосов
/ 27 января 2010

Вместо этого используйте панель док-станции

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