Search code examples
wpfscrollbarpasswordbox

Why WPF PasswordBox is not scrollable


Can someone explain to me why the PasswordBox control is not scrollable.

Preview

As you can see when mouse cursor comes on PasswordBox, scrolling not work. I added default and custom PasswordBox, both had the same behavior.

This a sample project that I created for better demonstration.

<Window 
    x:Class="PasswordBoxDemo.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"
    mc:Ignorable="d"
    Title="MainWindow" 
    Height="450"
    Width="600"
    WindowStartupLocation="CenterScreen">
    <Window.Resources>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Padding" Value="12,8"/>
            <Setter Property="Text" Value="Sample text"/>
        </Style>

        <Style TargetType="{x:Type PasswordBox}">
            <Setter Property="Padding" Value="12,8"/>
        </Style>
    </Window.Resources>
    <ScrollViewer>
        <StackPanel Margin="10" Height="800">
            <TextBlock Margin="16" FontSize="32" TextWrapping="Wrap">
                Put your mouse on password box area and try to scroll by mouse wheel.
            </TextBlock>
            <Label>Text:</Label>
            <TextBox />
            <Label>Password:</Label>
            <PasswordBox Password="123456"/>
            <Label>Text:</Label>
            <TextBox />
            <Label>Text:</Label>
            <TextBox />
            <Label>Password:</Label>
            <PasswordBox Password="123456"/>
            <Label>Text:</Label>
            <TextBox />
            <Label>Text:</Label>
            <TextBox />
        </StackPanel>
    </ScrollViewer>
</Window>


Solution

  • This looks like the scroll mouse event is suppressed on the password box internally. You could do something like setting IsHitTestVisible to false, however this would stop other mouse events from happening as well.

    If you just need a no frills work around, add a handler for the PreviewMouseWheel event like so:

    <PasswordBox PreviewMouseWheel="PasswordBox_PreviewMouseWheel" />
    

    Give your parent ScrollViewer a name:

    <ScrollViewer Name="scrollViewer1">
    

    Then in code implement the handler callback something like this:

    private void PasswordBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (e.Delta != 0)
        {
            scrollViewer1.ScrollToVerticalOffset(scrollViewer1.VerticalOffset - e.Delta);
        }
        e.Handled = true;
    }
    

    It's a big ugly, but works.