Question

I am trying to fix a larger block of code written by previous colleague - it i some sort of report system, output is a table with data. My task was to freeze column headerson top when scrolling. As i am new to this, I made very simple table, to find out how datagrid works:

    public MainWindow()
    {
        this.InitializeComponent();

        var dt = new DataTable();
        dt.Columns.Add("prvni");
        dt.Columns.Add("druhy");

        for (int i = 0; i < 100; i++)
        {
            var row = dt.NewRow();
            row[0] = "A" + i;
            row[1] = "B" + i;
            dt.Rows.Add(row);
        }

        this.MainGrid.ItemsSource = dt.AsDataView();
    }

By lots of searching, I found many topics, which recommended to get rid of ScrollViewer, as the freezed headers are in datagrid by default. This was the original part of code I modified:

        var scrollViewer = new ScrollViewer()
        {
            HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
            VerticalScrollBarVisibility = ScrollBarVisibility.Auto
        };

        scrollViewer.AddHandler(UIElement.MouseWheelEvent, new RoutedEventHandler(this.MouseWheelHandler), true);
        var stackPanel = new StackPanel();
        scrollViewer.Content = stackPanel;

        ...

        return scrollViewer;

And in another function, it was used/called as:

        var reportInfo = ((((sender as DataGrid).Parent as StackPanel).Parent as ScrollViewer).Parent as ReportOutputTabItem).Tag as ReportInfo;

Well - I removed the scrollviewer, and was returning it as StackPanel, however - now I cannot scroll at all. When I searched questions, how to add vertical scrolling to StackPanel, answers were "add ScrollViewer".

So - is there a way, how either make column headers freezed inside the ScrollViewer, or how to enable vertical scrolling in StackPanel without using scrollViewer? (and another possible solution might be to make the vertical size of StackPanel bit shorter, as there are mostly pages of results, but full page is still required to scroll a bit).

XAML part:

<Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <TabControl Name="MainTab" SelectionChanged="MainTabSelectionChanged" ItemTemplate="{StaticResource ClosableTabItemTemplate}"/>

        <StackPanel Grid.Row="1" Name="NavigationPanel" Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Height="23" Name="FirstButton" Width="40" Content="&lt;&lt;" Click="PageButtonClick" Opacity="0.75"/>
            <Button Height="23" Name="PrevButton" Width="40" Click="PageButtonClick" Opacity="0.75" Content="&lt;"/>
            <Label Height="23" Name="PageNumberLabel" Width="70" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="1/1"/>
            <Button Height="23" Name="NextButton" Width="40" Content=">" Click="PageButtonClick" Opacity="0.75"/>
            <Button Height="23" Name="LastButton" Width="40" Click="PageButtonClick" Opacity="0.75" Content=">>"/>
        </StackPanel>

Thanks in advance.

Was it helpful?

Solution

Well, I finally found solution to this: Originally, the datagrid was wrapped in the StackPanel, and then in ScrollViewer. I removed the ScrollViewer, and replaces StackPanel with Grid.

Now I have both vertical scrollbars, and frozen column headers.

I removed the entire

var scrollViewer = new ScrollViewer()
{
    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
    VerticalScrollBarVisibility = ScrollBarVisibility.Auto
};

scrollViewer.AddHandler(UIElement.MouseWheelEvent, new RoutedEventHandler(this.MouseWheelHandler), true);
var stackPanel = new StackPanel();
scrollViewer.Content = stackPanel; 

and replaced with simple var grid = new Grid();

and all stackPanel.Children.Add(dataGrid); replaced with grid.Children.Add(dataGrid);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top