检测滚动条在 UWP 中何时可见
Detect when scrollbar is visible in UWP
在 UWP 中使用 ScrollViewer
,我需要检测滚动条或平移指示器何时可见,以便我可以向 ScrollViewer 添加填充,以便滚动条在可见时不会与内容重叠观众。
SO 上对 Detect, if ScrollBar of ScrollViewer is visible or not 的回复看起来很有希望,但它是为 WPF 编写的。它确实将我引向 UWPScrollViewer
中也存在的 ComputedVerticalScrollBarVisibility
属性,但是它始终具有 Visible
的值,即使滚动条隐藏在用户界面中。
XAML片段:
<ScrollViewer
Name="ForegroundElement"
VerticalScrollMode="Auto">
<Grid>
<Frame x:Name="shellFrame" />
</Grid>
</ScrollViewer>
ComputedVerticalScrollBarVisibility
的文档表明这是最合适的 属性 来确定滚动条是否可见,另一方面 VerticalScrollBarVisibility
属性 用于指明您是否希望垂直滚动条完全可用。
ComputedVerticalScrollBarVisibility
A Visibility that indicates whether the vertical scroll bar is visible. The default is Visible.
that last bit is confusing, it looks as if this property always stays in the default state.
最初我尝试在代码隐藏中为 ComputedVerticalScrollBarVisibilityProperty
注册一个更改处理程序,作为一个概念,它通常可以很好地拦截对 依赖属性 的控件的更改不公开特定的更改事件,但以下实现从未注册过更改:
public ShellPage()
{
InitializeComponent();
// register for property change on the scrollbar, add padding to the page
ForegroundElement.RegisterPropertyChangedCallback(
ScrollViewer.ComputedVerticalScrollBarVisibilityProperty,
ForegroundElement_ScrollBarVisibilityChanged);
}
private void ForegroundElement_ScrollBarVisibilityChanged(DependencyObject sender, DependencyProperty dp)
{
if (ForegroundElement.ComputedVerticalScrollBarVisibility == Visibility.Visible)
{
if (ForegroundElement.Padding.Right != 18)
ForegroundElement.Padding = new Thickness(0, 0, 18, 0);
}
else
{
if (ForegroundElement.Padding.Right != 0)
ForegroundElement.Padding = new Thickness(0);
}
}
更改实施以监听 LayoutUpdated Event 并没有多大帮助,因为 ComputedVerticalScrollBarVisibility
的值始终是 Visible
,即使滚动条在 UI.
我仔细检查了 VerticalScrollMode
是否设置为 "Auto"
因为我知道这在其他平台中是一个问题,但是更改此值或完全省略它没有任何影响。
背景
虽然 MS implementation of the scrollbar in modern Windows 10 store apps 和 Edge 浏览器被 pro-windows 社区有很好的记录和普遍容忍,因为它被视为OS,这种隐藏滚动条直到用户将鼠标悬停在滚动条上的默认行为导致我们的 UWP 应用在市场上收到大量负面用户反馈。平移指示器太微妙了,我们的用户感到困惑,因为他们根本不知道区域可以滚动。
For this post I have focussed specifically on a declared ScrollViewer
, however the same issues apply to other standard controls that implement ScrollViewer
internally in their control templates.
ScrollViewer
上还有另一个 属性 可用于确定滚动条何时可见,ScrollableHeight
ScrollViewer.ScrollableHeight Property
Gets a value that represents the vertical size of the area that can be scrolled; the difference between the height of the extent and the height of the viewport.
因此,当 ScrollableHeight
为 0 时,滚动条将为 Collapsed
,对于所有其他正值,滚动条将为 Visible
.
此实现按预期工作:
public ShellPage()
{
InitializeComponent();
// register for property change on the scrollbar, add padding to the page
ForegroundElement.RegisterPropertyChangedCallback(
ScrollViewer.ScrollableHeightProperty,
ForegroundElement_ScrollableHeightChanged);
}
private void ForegroundElement_ScrollableHeightChanged(DependencyObject sender, DependencyProperty dp)
{
if (ForegroundElement.ScrollableHeight > 0)
{
if (ForegroundElement.Padding.Right != 18)
ForegroundElement.Padding = new Thickness(0, 0, 18, 0);
}
else
{
if (ForegroundElement.Padding.Right != 0)
ForegroundElement.Padding = new Thickness(0);
}
}
在 UWP 中使用 ScrollViewer
,我需要检测滚动条或平移指示器何时可见,以便我可以向 ScrollViewer 添加填充,以便滚动条在可见时不会与内容重叠观众。
SO 上对 Detect, if ScrollBar of ScrollViewer is visible or not 的回复看起来很有希望,但它是为 WPF 编写的。它确实将我引向 UWPScrollViewer
中也存在的 ComputedVerticalScrollBarVisibility
属性,但是它始终具有 Visible
的值,即使滚动条隐藏在用户界面中。
XAML片段:
<ScrollViewer
Name="ForegroundElement"
VerticalScrollMode="Auto">
<Grid>
<Frame x:Name="shellFrame" />
</Grid>
</ScrollViewer>
ComputedVerticalScrollBarVisibility
的文档表明这是最合适的 属性 来确定滚动条是否可见,另一方面 VerticalScrollBarVisibility
属性 用于指明您是否希望垂直滚动条完全可用。
ComputedVerticalScrollBarVisibility
A Visibility that indicates whether the vertical scroll bar is visible. The default is Visible.that last bit is confusing, it looks as if this property always stays in the default state.
最初我尝试在代码隐藏中为 ComputedVerticalScrollBarVisibilityProperty
注册一个更改处理程序,作为一个概念,它通常可以很好地拦截对 依赖属性 的控件的更改不公开特定的更改事件,但以下实现从未注册过更改:
public ShellPage()
{
InitializeComponent();
// register for property change on the scrollbar, add padding to the page
ForegroundElement.RegisterPropertyChangedCallback(
ScrollViewer.ComputedVerticalScrollBarVisibilityProperty,
ForegroundElement_ScrollBarVisibilityChanged);
}
private void ForegroundElement_ScrollBarVisibilityChanged(DependencyObject sender, DependencyProperty dp)
{
if (ForegroundElement.ComputedVerticalScrollBarVisibility == Visibility.Visible)
{
if (ForegroundElement.Padding.Right != 18)
ForegroundElement.Padding = new Thickness(0, 0, 18, 0);
}
else
{
if (ForegroundElement.Padding.Right != 0)
ForegroundElement.Padding = new Thickness(0);
}
}
更改实施以监听 LayoutUpdated Event 并没有多大帮助,因为 ComputedVerticalScrollBarVisibility
的值始终是 Visible
,即使滚动条在 UI.
我仔细检查了 VerticalScrollMode
是否设置为 "Auto"
因为我知道这在其他平台中是一个问题,但是更改此值或完全省略它没有任何影响。
背景
虽然 MS implementation of the scrollbar in modern Windows 10 store apps 和 Edge 浏览器被 pro-windows 社区有很好的记录和普遍容忍,因为它被视为OS,这种隐藏滚动条直到用户将鼠标悬停在滚动条上的默认行为导致我们的 UWP 应用在市场上收到大量负面用户反馈。平移指示器太微妙了,我们的用户感到困惑,因为他们根本不知道区域可以滚动。
For this post I have focussed specifically on a declared
ScrollViewer
, however the same issues apply to other standard controls that implementScrollViewer
internally in their control templates.
ScrollViewer
上还有另一个 属性 可用于确定滚动条何时可见,ScrollableHeight
ScrollViewer.ScrollableHeight Property
Gets a value that represents the vertical size of the area that can be scrolled; the difference between the height of the extent and the height of the viewport.
因此,当 ScrollableHeight
为 0 时,滚动条将为 Collapsed
,对于所有其他正值,滚动条将为 Visible
.
此实现按预期工作:
public ShellPage()
{
InitializeComponent();
// register for property change on the scrollbar, add padding to the page
ForegroundElement.RegisterPropertyChangedCallback(
ScrollViewer.ScrollableHeightProperty,
ForegroundElement_ScrollableHeightChanged);
}
private void ForegroundElement_ScrollableHeightChanged(DependencyObject sender, DependencyProperty dp)
{
if (ForegroundElement.ScrollableHeight > 0)
{
if (ForegroundElement.Padding.Right != 18)
ForegroundElement.Padding = new Thickness(0, 0, 18, 0);
}
else
{
if (ForegroundElement.Padding.Right != 0)
ForegroundElement.Padding = new Thickness(0);
}
}