Two methods of fixing WPF menu bar after scrolling to the top

Recently, there is a requirement in the project:

The menu bar is fixed at the top after scrolling to the top.. This is quite common on the mobile end

Look at the effect:

Let’s take a look at the code. There are not many codes

The first method is as follows:

Write a menu as like as two peas, and hide it on top of the window. When the menu is rolled up to the top, it will be displayed, otherwise hidden. br>

Mainwindow1.xaml is as follows:

<Window x:Class="wpfcore.MainWindow1"
        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:wpfcore"
        mc:Ignorable="d"
        Title="MainWindow1" Height="450" Width="800">
    <Grid>
        <ScrollViewer ScrollChanged="ScrollViewer_ScrollChanged">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="200"/>
                    <RowDefinition Height="auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid Grid.Row="0" x:Name="banner">
                    <Image Source="D:\bizhi\123\2-9.jpg" Stretch="UniformToFill" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" Foreground="White" Text="这是顶部Banner"/>
                </Grid>
                <StackPanel Grid.Row="1" Panel.ZIndex="100" x:Name="menu" Orientation="Horizontal" TextBlock.FontSize="18" Background="LightBlue">
                    <TextBlock Text="Home" Margin="10"></TextBlock>
                    <TextBlock Text="Editor" Margin="10"></TextBlock>
                    <TextBlock Text="Viewer" Margin="10"></TextBlock>
                    <TextBlock Text="Debug" Margin="10"></TextBlock>
                    <TextBlock Text="WPF UI" Margin="10"></TextBlock>
                </StackPanel>
                <Border Height="1000" Grid.Row="22">
                    <Border.Background>
                        <LinearGradientBrush>
                            <GradientStop Color="Red" Offset="0"/>
                            <GradientStop Color="Green" Offset="0.5"/>
                            <GradientStop Color="Blue" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.Background>
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" Foreground="White" Text="这是顶部Banner"/>
                </Border>
            </Grid>
        </ScrollViewer>
        <StackPanel x:Name="topMenu" VerticalAlignment="Top" Visibility="Hidden" Orientation="Horizontal" TextBlock.FontSize="18" Background="LightBlue">
            <TextBlock Text="Home" Margin="10"></TextBlock>
             <TextBlock Text="Editor" Margin="10"></TextBlock>
             <TextBlock Text="Viewer" Margin="10"></TextBlock>
             <TextBlock Text="Debug" Margin="10"></TextBlock>
            <TextBlock Text="WPF UI" Margin="10"></TextBlock>
        </StackPanel>
    </Grid>
</Window>

Mainwindow1.cs Code:

using System.Windows;


namespace wpfcore
{
    public partial class MainWindow1 : Window
    {
        public MainWindow1()
        {
            InitializeComponent();
        }
        private void ScrollViewer_ScrollChanged(object sender, System.Windows.Controls.ScrollChangedEventArgs e)
        {
            if (e.VerticalOffset > banner.ActualHeight)
            {
                 topMenu.Visibility = Visibility.Visible;
            }
            else
            {
                topMenu.Visibility = Visibility.Hidden;
            }
        }
    }
}

—————Dividing line——————

Second method:

Add render transform to the menu bar. When the menu scrolls to the top, set translatetransform. Yproperty   The same effect was achieved

Mainwindow.xaml code is as follows:

<Window x:Class="wpfcore.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:wpfcore" 
        xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
        mc:Ignorable="d"
        UseLayoutRounding="True"
        Title="MainWindow" Width="600" Height="340">
    <Grid>
        <ScrollViewer ScrollChanged="ScrollViewer_ScrollChanged">
            <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="200"/>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid Grid.Row="0" x:Name="banner">
                <Image Source="D:\bizhi\123\2-9.jpg" Stretch="UniformToFill" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" Foreground="White" Text="这是顶部Banner"/>
            </Grid>
            <StackPanel Grid.Row="1" Panel.ZIndex="100" x:Name="menu" Orientation="Horizontal" TextBlock.FontSize="18" Background="LightBlue">
                    <StackPanel.RenderTransform>
                        <TranslateTransform x:Name="menuTranslate" Y="0.0"/>
                    </StackPanel.RenderTransform>
                    <TextBlock Text="Home" Margin="10"></TextBlock>
                    <TextBlock Text="Editor" Margin="10"></TextBlock>
                    <TextBlock Text="Viewer" Margin="10"></TextBlock>
                    <TextBlock Text="Debug" Margin="10"></TextBlock>
                    <TextBlock Text="WPF UI" Margin="10"></TextBlock>
                </StackPanel>
            <Border Height="1000" Grid.Row="22">
                <Border.Background>
                    <LinearGradientBrush>
                        <GradientStop Color="Red" Offset="0"/>
                        <GradientStop Color="Green" Offset="0.5"/>
                        <GradientStop Color="Blue" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" Foreground="White" Text="这是顶部Banner"/>
                </Border>
        </Grid>
    </ScrollViewer>
        <StackPanel x:Name="topMenu" VerticalAlignment="Top" Visibility="Hidden" Orientation="Horizontal" TextBlock.FontSize="18" Background="LightBlue">
            <TextBlock Text="Home" Margin="10"></TextBlock>
            <TextBlock Text="Editor" Margin="10"></TextBlock>
            <TextBlock Text="Viewer" Margin="10"></TextBlock>
            <TextBlock Text="Debug" Margin="10"></TextBlock>
            <TextBlock Text="WPF UI" Margin="10"></TextBlock>
        </StackPanel>
    </Grid>
</Window>


Mainwindow.cs Code:

using System.Windows;
using System.Windows.Media;


namespace wpfcore
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }


        private void ScrollViewer_ScrollChanged(object sender, System.Windows.Controls.ScrollChangedEventArgs e)
        {
            menuTranslate.SetValue(TranslateTransform.YProperty, e.VerticalOffset);
            if (e.VerticalOffset > banner.ActualHeight)
            {
                menuTranslate.SetValue(TranslateTransform.YProperty, e.VerticalOffset-banner.ActualHeight);
            }
            else
            {
                menuTranslate.SetValue(TranslateTransform.YProperty, 0.0);
            }
        }
    }
}



Read More: