如何在滚动查看器中获取滚动条以在单击时聚焦滚动查看器?

时间:2021-01-31 21:17:50

Currently with a scrollviewer, clicking the scroll bar contained in it to pan the content around it will not focus the viewer (or anything for that matter). I wish to have it so when you scroll by dragging the scroll, or even clicking the scrollbar will focus the parent (scroll viewer).

目前使用滚动查看器,单击其中包含的滚动条以平移其周围的内容将不会使查看器(或任何其他事项)聚焦。我希望如此,当您通过拖动滚动滚动,甚至单击滚动条将聚焦父(滚动查看器)。

I achieved this somewhat by attaching a ScrollChanged handler on the scrollviewer and calling sender.focus(). Unforutnally ScrollChanged is called on initialising the scrollviewer and so on loading the

我通过在scrollviewer上附加一个ScrollChanged处理程序并调用sender.focus()来实现这一点。在初始化scrollviewer时调用ScrollChanged,然后加载

I also tried attaching event setters with still no luck.

我也试过附上事件制定者仍然没有运气。

Ideally I would like it on some sort of style or something which allows me to apply it to all scrollviewers across the entire application.

理想情况下,我想在某种风格或某些东西上允许我将它应用于整个应用程序中的所有滚动查看器。

Edit: Just for futher clarification, if I use this xaml and click on the scroll bar it will not turn the background blue (gotfocus event). When I click inside the scroll viewer or the button it will.

编辑:为了进一步澄清,如果我使用此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 个解决方案

#1


4  

I'm not 100% certain what you are looking for here but adding this code to your example will make the ScrollViewer receive focus when the ScrollBar is clicked, dragged etc. Some code behind is required for this solution though.

我不是100%肯定你在这里寻找什么,但是在你的例子中添加这些代码将使ScrollViewer在点击,拖动等ScrollBar时获得焦点。但是这个解决方案需要一些代码。

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

And in code behind

并在代码背后

void scrollBar_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    c_scrollViewer.Focus();
}

UPDATE

UPDATE

You may know how to add this to a Resource Dictionary so you can access it for multiple ScrollViewers, otherwise here is how you can do it.

您可能知道如何将其添加到资源字典中,以便您可以为多个ScrollViewer访问它,否则您可以按照以下方式执行此操作。

Add a Resource Dictionary to your project. I called mine ScrollBarStyles.xaml.
Add a code behind class for it, called ScrollBarStyles.xaml.cs.
Add an x:Class attribute in the xaml file, something like

将资源字典添加到项目中。我打电话给我的ScrollBarStyles.xaml。为它添加一个代码,名为ScrollBarStyles.xaml.cs。在xaml文件中添加x:Class属性,类似于

x:Class="YourNameSpace.ScrollBarStyles"

ScrollBarStyles.xaml

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

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();
    }
}

Your Window

你的窗口

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

#1


4  

I'm not 100% certain what you are looking for here but adding this code to your example will make the ScrollViewer receive focus when the ScrollBar is clicked, dragged etc. Some code behind is required for this solution though.

我不是100%肯定你在这里寻找什么,但是在你的例子中添加这些代码将使ScrollViewer在点击,拖动等ScrollBar时获得焦点。但是这个解决方案需要一些代码。

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

And in code behind

并在代码背后

void scrollBar_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    c_scrollViewer.Focus();
}

UPDATE

UPDATE

You may know how to add this to a Resource Dictionary so you can access it for multiple ScrollViewers, otherwise here is how you can do it.

您可能知道如何将其添加到资源字典中,以便您可以为多个ScrollViewer访问它,否则您可以按照以下方式执行此操作。

Add a Resource Dictionary to your project. I called mine ScrollBarStyles.xaml.
Add a code behind class for it, called ScrollBarStyles.xaml.cs.
Add an x:Class attribute in the xaml file, something like

将资源字典添加到项目中。我打电话给我的ScrollBarStyles.xaml。为它添加一个代码,名为ScrollBarStyles.xaml.cs。在xaml文件中添加x:Class属性,类似于

x:Class="YourNameSpace.ScrollBarStyles"

ScrollBarStyles.xaml

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

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();
    }
}

Your Window

你的窗口

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