haku
haku

Reputation: 4505

How to dock a grid to the top?

In WPF, how do I dock a grid to the top? I have a Grid and ItemsControl inside a DockPanel. The first grid serves as column headers and I don't want them to scroll as I scroll through the content of the ItemsControl. I tried setting DockPanel.Dock="Top" but that didn't get the grid to stick/freeze on top.

Below is minimal/simpler replica of my situation.

XAML:

<Window x:Class="SimplerOne.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SimplerOne"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.Resources>
    <CollectionViewSource x:Key="years" Source="{Binding Years}" />
</Window.Resources>
<Grid>
    <ScrollViewer HorizontalScrollBarVisibility="Auto">
        <DockPanel LastChildFill="True">
            <Grid DockPanel.Dock="Top">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition></RowDefinition>
                </Grid.RowDefinitions>
                <!-- i have some items control that expand horizontally for col headers here. I want it to stick to the top.-->
                <TextBlock Text="headers"></TextBlock>
            </Grid>

            <ItemsControl x:Name="icContents" ItemsSource="{Binding Source={StaticResource years}}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Year}"></TextBox>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DockPanel>
    </ScrollViewer>
</Grid>

In code behind:

public partial class MainWindow : Window
{
    private ObservableCollection<RunYear> _years = new ObservableCollection<RunYear>();
    public ObservableCollection<RunYear> Years { get{return _years; } }
    public MainWindow()
    {
        DataContext = this;
        InitializeComponent();
        GenerateData();
    }

    private void GenerateData()
    {
        for (int i = 2010; i < 2075; i++)
        {

           Years.Add(new RunYear(i));
        }
    }
}

Upvotes: 1

Views: 91

Answers (1)

Sach
Sach

Reputation: 10393

Your second Grid is inside the ScrollViewer so it will obviously scroll. You should have it outside.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <!-- i have some items control that expand horizontally for col headers here. I want it to stick to the top.-->
        <TextBlock Text="headers"></TextBlock>
    </Grid>
    <ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto">
        <DockPanel LastChildFill="True">
            <ItemsControl x:Name="icContents" ItemsSource="{Binding Source={StaticResource years}}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Year}"></TextBox>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DockPanel>
    </ScrollViewer>
</Grid>

EDIT

Option 2:

<Grid>
    <DockPanel LastChildFill="True">
        <Grid DockPanel.Dock="Top">
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <!-- i have some items control that expand horizontally for col headers here. I want it to stick to the top.-->
            <TextBlock Text="headers"></TextBlock>
        </Grid>
        <ScrollViewer HorizontalScrollBarVisibility="Auto">

            <ItemsControl x:Name="icContents" ItemsSource="{Binding Source={StaticResource years}}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Year}"></TextBox>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </DockPanel>
</Grid>

Upvotes: 1

Related Questions