当在ScrollViewer中单击滚动条时,如何使ScrollViewer获得焦点?

3

目前,使用滚动视图器中的滚动条来平移其周围的内容时,将不会聚焦于视图器(或其他任何东西)。我希望当您通过拖动滚动条或单击滚动条滚动时,可以聚焦于父级(滚动视图器)。

我通过在滚动视图器上附加ScrollChanged处理程序并调用sender.focus()来实现了这一点。但不幸的是,在初始化滚动视图器时会调用ScrollChanged,因此在加载时也会调用。

我还尝试过附加事件设置器,但仍然没有运气。

理想情况下,我希望它能够应用于整个应用程序中的所有滚动视图器,例如某种样式或其他方式。

编辑:为了进一步澄清,如果我使用此xaml并单击滚动条,则不会使背景变蓝(gotfocus事件)。当我单击滚动视图器内部或按钮时,它会。

<Window x:Class="GotFocusProblem.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid Margin="20" x:Name="grid">
            <Grid.Background>
                <SolidColorBrush x:Name="backgrnd" Color="Transparent"/>
            </Grid.Background>
            <ScrollViewer Margin="10" Height="100" Background="#FFEEEEEE">
                <Button Content="Button" Name="button1" Height="300"  Width="75" />
            </ScrollViewer>
            <Grid.Triggers>
                <EventTrigger RoutedEvent="Grid.GotFocus">
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimation
                            Storyboard.TargetName="backgrnd"
                            Storyboard.TargetProperty="Color"
                            To="Cyan"
                            BeginTime="0:0:0"
                            Duration="0:0:0" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Grid.Triggers>
        </Grid>
    </Grid>
</Window>
1个回答

4

我不完全确定您在这里寻找什么,但是将以下代码添加到您的示例中将使ScrollViewer在单击、拖动等ScrollBar时获得焦点。但是,这种解决方案需要一些代码支持。

<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
    <EventSetter Event="PreviewMouseDown" Handler="scrollBar_PreviewMouseDown"/>            
</Style>

在代码后台中
void scrollBar_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    c_scrollViewer.Focus();
}

更新

您可能已经知道如何将此添加到资源字典中,以便您可以在多个ScrollViewers中访问它,否则以下是如何操作。

将资源字典添加到您的项目中。我称之为ScrollBarStyles.xaml。
为其添加一个代码后台类,称为ScrollBarStyles.xaml.cs。
在xaml文件中添加x:Class属性,例如

x:Class="YourNameSpace.ScrollBarStyles"

ScrollBarStyles.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    x:Class="FocusScrollViewer.ScrollBarStyles">
    <Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
        <EventSetter Event="PreviewMouseDown" Handler="scrollBar_PreviewMouseDown"/>
    </Style>
</ResourceDictionary>

ScrollBarStyles.xaml.cs

public partial class ScrollBarStyles
{
    public T GetVisualParent<T>(object childObject) where T : Visual
    {
        DependencyObject child = childObject as DependencyObject;
        // iteratively traverse the visual tree
        while ((child != null) && !(child is T))
        {
            child = VisualTreeHelper.GetParent(child);
        }
        return child as T;
    }

    void scrollBar_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        ScrollBar scrollBar = sender as ScrollBar;
        ScrollViewer scrollViewer = GetVisualParent<ScrollViewer>(scrollBar);
        scrollViewer.Focus();
    }
}

您的窗口

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ScrollBarStyles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

这是一个非常好的答案。谢谢你。虽然我之前已经为特定的滚动条编写了代码,以便像你一样进行聚焦,但我不知道如何在样式中实现它。事实上,我没有意识到资源字典可以有代码后台。非常有价值的信息。谢谢! - Seravy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接