如何在 C# 中找到 Scrollviewer 的垂直滚动条宽度

发布于 2024-11-02 11:01:44 字数 282 浏览 2 评论 0原文

我有一个 ScrollViewer,其中显示垂直滚动条,现在在更改系统分辨率时我想获取滚动条的宽度。我浏览了一篇 StackOverflow 帖子他们提到要检查 SystemParameters.ScrollWidth 属性,但我再次从他们那里找到任何帮助。任何人都可以帮我解决我的问题吗?任何答案将不胜感激。

I have a ScrollViewer and in that I am showing the Vertical Scrollbar, Now on changing resolution of the system I want to get the width of the scrollbar. I went through One StackOverflow Post there they mention to check for SystemParameters.ScrollWidth Property but again I din find any help from their. Can anybody please help me to fix my issue. Any answer will be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ゃ人海孤独症 2024-11-09 11:01:44

我不确定这是否是正确的答案。每个 WPF 控件都可以重新设计样式,甚至滚动条也是如此。因此,SystemParameters.VerticalScrollBarWidth 仅在用作默认滚动条时才有效。正确的解决方案是在可视化树中找到垂直滚动条并测量它的实际宽度。这是最精确的测量。

I am not sure if this is the correct answer. Every WPF control can be restyled so even the scrollbar. So SystemParameters.VerticalScrollBarWidth works only if it is used as default scrollbar. The correct solution would be to find the vertical scrollbar in the visual tree and measure it's ActualWidth. It is the most precise measurement.

南冥有猫 2024-11-09 11:01:44

正如一些答案所建议的,SystemParameters.VerticalScrollBarWidth 返回用于系统控件的常量。
然而,这个值并不可靠。例如,ScrollBar 元素可以进行自定义,或者将其可见性设置为 Visibility.Collapsed(这样它们就不再是可视化树的子级,因此不会影响不再渲染布局)。

要获取当前宽度,您必须在 ScrollViewer 的可视化树中找到滚动条。
ScrollViewerScrollBar 元素定义为名为 "PART_VerticalScrollBar""PART_Horizo​​ntalScrollBar" 的模板部件。

您可以使用以下扩展方法(扩展DependencyObject)来获取垂直ScrollBar
用法
例如,要获取 DataGrid 控件的垂直 ScrollViewerScrollBar 宽度,请使用

if (dataGrid.TryFindVisualChildElementByName("PART_VerticalScrollBar", out ScrollBar scrollbar))
{
  double verticalScrolBarWidth = scrollbar.Width;
}
public static class VisualTreeHelperExtensions
{
  public static bool TryFindVisualChildElementByName<TChild>(
    this DependencyObject parent, 
    string childElementName, 
    out TChild resultElement) where TChild : FrameworkElement
  {
    resultElement = null;
    if (parent is Popup popup)
    {
      parent = popup.Child;
      if (parent == null)
      {
        return false;
      }
    }

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
    {
      DependencyObject child = VisualTreeHelper.GetChild(parent, i);
      if (child is FrameworkElement frameworkElement 
        && frameworkElement.Name.Equals(childElementName, StringComparison.OrdinalIgnoreCase))
      {
        resultElement = frameworkElement as TChild;
        return true;
      }

      if (child.TryFindVisualChildElementByName<TChild>(childElementName, out resultElement))
      {
        return true;
      }
    }

    return false;
  }
}

As suggested by some answers, SystemParameters.VerticalScrollBarWidth returns the constant that is used for system controls.
However, this value is not reliable. For example, the ScrollBar elements could have been customized or have their visibility set to Visibility.Collapsed (so that they are no longer a child of the visual tree and therefore not impacting the rendered layout anymore).

To get the current width you must locate the scroll bars in the visual tree of the ScrollViewer.
The ScrollViewer defines the ScrollBar elements as template parts named "PART_VerticalScrollBar" and "PART_HorizontalScrollBar".

You can use the following extension method (extending DependencyObject) to get the vertical ScrollBar:
Usage
For example, to get the ScrollBar width of the vertical ScrollViewer of the DataGrid control use

if (dataGrid.TryFindVisualChildElementByName("PART_VerticalScrollBar", out ScrollBar scrollbar))
{
  double verticalScrolBarWidth = scrollbar.Width;
}
public static class VisualTreeHelperExtensions
{
  public static bool TryFindVisualChildElementByName<TChild>(
    this DependencyObject parent, 
    string childElementName, 
    out TChild resultElement) where TChild : FrameworkElement
  {
    resultElement = null;
    if (parent is Popup popup)
    {
      parent = popup.Child;
      if (parent == null)
      {
        return false;
      }
    }

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
    {
      DependencyObject child = VisualTreeHelper.GetChild(parent, i);
      if (child is FrameworkElement frameworkElement 
        && frameworkElement.Name.Equals(childElementName, StringComparison.OrdinalIgnoreCase))
      {
        resultElement = frameworkElement as TChild;
        return true;
      }

      if (child.TryFindVisualChildElementByName<TChild>(childElementName, out resultElement))
      {
        return true;
      }
    }

    return false;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文