检查滚动条可见性

问题描述 投票:3回答:2

是否有办法检查垂直滚动条在某个ListView对象上是否可见?

我有一个带有listView的Windows窗体,在resize事件上,如果listview的“垂直滚动条”可见,我想抓住它!

c# winforms listview scrollbar visibility
2个回答
3
投票
如果这是WinForms,则可以使用pinvoke和GetWindowLong ...

static public class WndInfo { [DllImport("user32.dll", SetLastError = true)] static extern int GetWindowLong(IntPtr hWnd, int nIndex); ... public static bool IsWindowTopMost(IntPtr Handle) { return (GetWindowLong(Handle, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; } ... }

[VB code exists使用GetWindowLong检查是否存在可以移植到C#的ScrollBar。


0
投票
public static class NativeMethods { const Int32 LVM_FIRST = 0x1000; const Int32 LVM_SCROLL = LVM_FIRST + 20; [DllImport("user32")] static extern IntPtr SendMessage(IntPtr Handle, Int32 msg, IntPtr wParam, IntPtr lParam); // offset of window style value const int GWL_STYLE = -16; // window style constants for scrollbars const int WS_VSCROLL = 0x00200000; const int WS_HSCROLL = 0x00100000; [DllImport("user32.dll", SetLastError = true)] static extern int GetWindowLong(IntPtr hWnd, int nIndex); static ScrollBars GetControlVisibleScrollbars(Control ctl) { int wndStyle = GetWindowLong(ctl.Handle, GWL_STYLE); bool hsVisible = (wndStyle & WS_HSCROLL) != 0; bool vsVisible = (wndStyle & WS_VSCROLL) != 0; if(hsVisible) return vsVisible ? ScrollBars.Both : ScrollBars.Horizontal; else return vsVisible ? ScrollBars.Vertical : ScrollBars.None; } public static ScrollBars GetVisibleScrollbars(this ListView lv) { if(lv is null) { throw new ArgumentNullException(nameof(lv)); } return GetControlVisibleScrollbars(lv); } public static ScrollBars GetVisibleScrollbars(this ScrollableControl ctl) { if(ctl is null) { throw new ArgumentNullException(nameof(ctl)); } if(ctl.HorizontalScroll.Visible) return ctl.VerticalScroll.Visible ? ScrollBars.Both : ScrollBars.Horizontal; else return ctl.VerticalScroll.Visible ? ScrollBars.Vertical : ScrollBars.None; } private static void ScrollHorizontal(Form form, int pixelsToScroll) { SendMessage(form.Handle, LVM_SCROLL, (IntPtr)pixelsToScroll, IntPtr.Zero); } public static void EnsureVisible(this ListViewItem item, int subItemIndex, int margin=10) { if(item is null) { throw new ArgumentNullException(nameof(item)); } if( subItemIndex > item.SubItems.Count - 1) { throw new IndexOutOfRangeException($"ListView {item.ListView.Name} does not have a SubItem on index {subItemIndex}"); } // scroll to the item row. item.EnsureVisible(); Rectangle bounds = item.SubItems[subItemIndex].Bounds; bounds.Width = item.ListView.Columns[subItemIndex].Width; ScrollToRectangle(item.ListView,bounds,margin); } private static void ScrollToRectangle(ListView listView, Rectangle bounds, int margin) { int scrollToLeft = bounds.X + bounds.Width + margin; if(scrollToLeft > listView.Bounds.Width) { ScrollHorizontal(listView.FindForm(),scrollToLeft - listView.Bounds.Width); } else { int scrollToRight = bounds.X - margin; if(scrollToRight < 0) { ScrollHorizontal(listView.FindForm(),scrollToRight); } } }

在您的用例中,您有一个拆分器面板,并且您希望左侧面板足够宽而没有水平滚动条,那么您可以这样做:

var bar= MyListView.GetVisibleScrollbars();
while(bar== ScrollBars.Horizontal || bar== ScrollBars.Both)
{
    progressPanels.SplitterDistance += 5;
    bar = MyListView.GetVisibleScrollbars();
}

我并不是说这是最好的方法,我只是说这是一种选择,尤其是当处理不同DPI中的多个显示器时

© www.soinside.com 2019 - 2024. All rights reserved.