返回

如何在 .NET MAUI WinUI 中轻松获取 Microsoft.UI.Xaml.Controls.Primitives.ScrollBar

windows

在 .NET MAUI WinUI 中获取 Microsoft.UI.Xaml.Controls.Primitives.ScrollBar

问题

在 .NET MAUI 应用程序中,确定是否按下了 Microsoft.UI.Xaml.Controls.Primitives.ScrollBar 对于某些交互场景至关重要。我们尝试通过连接 PointerPressed 事件并从 PointerRoutedEventArgs 中的 OriginalSource 的父级循环遍历来检索滚动条,但希望了解是否存在更有效的方法。

解决方案

直接引用

如果你知道触发 PointerPressed 事件的特定滚动条,你可以直接引用它:

var scrollBar = sender as ScrollBar;

使用 VisualTreeHelper

VisualTreeHelper 提供了一个高效的方法来遍历控件的父元素:

DependencyObject parent = VisualTreeHelper.GetParent(sender as DependencyObject);
while (parent != null)
{
    if (parent is ScrollBar)
    {
        var scrollBar = parent as ScrollBar;
        break;
    }
    parent = VisualTreeHelper.GetParent(parent);
}

使用 FindAncestor

FindAncestor 方法允许你根据类型向上遍历控件的父元素:

var scrollBar = sender.FindAncestor<ScrollBar>();

使用 XAML 绑定

如果你知道滚动条的名称,可以使用 XAML 绑定来获取它:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2023/xaml/assembly/Microsoft.Maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <ScrollBar x:Name="MyScrollBar" />
</ContentPage>
var scrollBar = this.FindByName<ScrollBar>("MyScrollBar");

最佳做法

  • 使用特定于平台的方法: 对于高效率,请使用 VisualTreeHelper 等特定于 WinUI 的方法。
  • 避免名称查找: 如果你不知道滚动条的名称,请使用其他方法来获取它。名称查找可能很慢且不灵活。
  • 在事件处理程序中直接引用: 当直接引用滚动条时,这种方法是最有效的。

示例代码

private void PointerPressed(object sender, PointerRoutedEventArgs e)
{
    // 直接引用滚动条(如果适用)
    if (sender is ScrollBar scrollBar)
    {
        // 执行操作
        return;
    }

    // 使用 VisualTreeHelper 查找滚动条
    DependencyObject parent = VisualTreeHelper.GetParent(sender as DependencyObject);
    while (parent != null)
    {
        if (parent is ScrollBar scrollBar)
        {
            // 执行操作
            break;
        }
        parent = VisualTreeHelper.GetParent(parent);
    }
}

常见问题解答

问:我尝试了这些方法,但仍然无法获取滚动条。
答: 请确保你已正确地应用了适当的方法。确保你正在使用正确的控件类型,并且你在事件处理程序中获取 OriginalSource

问:是否有其他方法可以获取滚动条?
答: 可以使用自动化框架来获取滚动条和其他 UI 元素。但是,这种方法可能比较复杂且低效。

问:我如何确定触发 PointerPressed 事件的滚动条是否处于活动状态?
答: 你可以检查滚动条的 IsActive 属性,该属性指示滚动条是否正在接收指针输入。

问:是否有办法仅在滚动条处于活动状态时获取它?
答: 是的,你可以通过连接 PointerCaptureLost 事件来实现。当滚动条不再处于活动状态时,此事件将触发。

问:这些方法是否适用于其他类型的控件?
答: 这些方法可以用于获取任何类型的控件。但是,具体实现可能因控件类型而异。