Laden...

Scrollbar vorhanden? Wie überprüfen?

Erstellt von handycommander vor 15 Jahren Letzter Beitrag vor 14 Jahren 1.926 Views
handycommander Themenstarter:in
415 Beiträge seit 2006
vor 15 Jahren
Scrollbar vorhanden? Wie überprüfen?

Hi,

ich würd gern in meiner Listview überprüfen, ob eine Scrollbar vorhanden und im moment angezeigt wird...
Wie kann ich sowas rausfinden?

MfG
Tobi

3.971 Beiträge seit 2006
vor 15 Jahren

Du nimmst das letzte Item und prüfst mit der Position-Eigenschaft ob der entsprechende Wert größer als die aktuelle Höhe oder Breite ist.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo kleines_eichhoernchen,

das müsste man außerdem für den ersten Eintrag machen und wenn einer von beiden außerhalb ist, ist ein Scrollbar da. Nun den letzten Eintrag zu prüfen, reicht nicht, denn die Liste könnte ja ans Ende gescrollt sein.

herbivore

3.971 Beiträge seit 2006
vor 15 Jahren

Stimmt,
was aber auch nicht richtig funktioniert, wenn die Anzahl der Elemente um 1 größer ist, als ohne Scrollbar angezeigt wird, die X-Y-Position aber immer noch über der Scrollbar liegt. Leider hat das ListViewItem keine Höhe oder Size-Eigenschaft.

Die Size einer Standard Scrollbar bekommt man ja beim Erstellen einer neuen tempoären Scrollbar.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

4.506 Beiträge seit 2004
vor 15 Jahren

Hallo zusammen,

habe folgende Aussage nicht verifiziert, könnt also auch falsch liegen:

Meist gibt es eine PreferredSize Eigenschaft. Wenn man diesen Wert mit der tatsächlichen Größe vergleicht, dann sollte man festellen können, ob Scrollbars angezeigt werden.

Sicherer ist es aber definitiv über die Win-API zu gehen, so wie Th69 es angegeben hat.

Grüße
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

R
344 Beiträge seit 2006
vor 14 Jahren

Hallo alle,

weis nicht ob veraltet, aber habe mir das einmal angesehen.
Dabei habe ich festgestellt, dass bei Erscheinen und Verschwinden einer Scrollbar die Message WM_SIZE kommt.

Nun könnte man aufgrund der dann in LParam liegenden Größe genaue Schlüsse ziehen ob und welche Scrollbar sichtbar ist.

Die Funktion aus obigem Beitrag liefert aber noch mehr Werte mit denen ich auf das ScrollValue schließen konnte.

Dabei ist das entstanden:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace ListViewTest
{
    class ScrollEventArgs : EventArgs
    {
        public ScrollEventArgs(bool _isVisible)
        {
            this.isVisible = _isVisible;
        }
        public bool IsVisible
        {
            get
            {
                return (isVisible);
            }
        }
        bool isVisible;
    }
    class ScrollListView : ListView
    {
        public delegate void EventHandler(Object sender, ScrollEventArgs e);
        public event EventHandler VScrollBarVisibleChanged;
        public event EventHandler HScrollBarVisibleChanged;
        public enum WindowsMessages : int
        {
            WM_SIZE = 0x0005,
        }

        public short LOWORD(int l)
        { return ((short)(l & 0xffff)); }

        public short HIWORD(int l)
        { return ((short)(l >> 16)); }

        void SetScollBarVisibility(OBJID which, bool isVisible)
        {
            switch (which)
            {
                case OBJID.HSCROLL:
                    if (isHScrollBarVisible != isVisible)
                    {
                        isHScrollBarVisible = isVisible;
                        if (HScrollBarVisibleChanged != null)
                        {
                            HScrollBarVisibleChanged(this, new ScrollEventArgs(isVisible));
                        }
                    }
                    break;
                case OBJID.VSCROLL:
                    if (isVScrollBarVisible != isVisible)
                    {
                        isVScrollBarVisible = isVisible;
                        if (VScrollBarVisibleChanged != null)
                        {
                            VScrollBarVisibleChanged(this, new ScrollEventArgs(isVisible));
                        }
                    }
                    break;
            }
        }


        bool isVScrollBarVisible = false;
        public bool IsVScrollBarVisible
        {
            get { return isVScrollBarVisible; }
        }

        bool isHScrollBarVisible = false;
        public bool IsHScrollBarVisible
        {
            get { return isHScrollBarVisible; }
        }    

        protected override void DefWndProc(ref Message m)
        {
            base.DefWndProc(ref m);
            switch (m.Msg)
            {
                case (int)WindowsMessages.WM_SIZE:
                    SetScollBarVisibility(OBJID.HSCROLL, IsScrollBarVisible(OBJID.HSCROLL));
                    SetScollBarVisibility(OBJID.VSCROLL, IsScrollBarVisible(OBJID.VSCROLL));
                    break;
                default:
                    break;
            }
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // ScrollListView
            // 
            this.ResumeLayout(false);

        }

        [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetScrollBarInfo")]
        private static extern int GetScrollBarInfo(IntPtr hWnd,
        OBJID idObject, ref SCROLLBARINFO sbi);

        [StructLayout(LayoutKind.Sequential)]
        public struct SCROLLBARINFO
        {
            public int cbSize;
            public RECT rcScrollBar;
            public int dxyLineButton;
            public int xyThumbTop;
            public int xyThumbBottom;
            public int reserved;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public int[] rgstate;
        }

        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        enum OBJID : uint
        {
            /// <summary>Die horizontale ScrollBar.</summary>
            HSCROLL = 0xFFFFFFFA,
            /// <summary>Die vertikale Scrollbar.</summary>
            VSCROLL = 0xFFFFFFFB
        }

        private bool IsScrollBarVisible(OBJID scrollBar)
        {
            SCROLLBARINFO sbi = GetSbi(scrollBar);
            return sbi.rgstate[0] == 0;
        }
        SCROLLBARINFO GetSbi(OBJID scrollBar)
        {
            SCROLLBARINFO sbi = new SCROLLBARINFO();
            sbi.cbSize = Marshal.SizeOf(sbi);
            int result = GetScrollBarInfo(Handle, scrollBar, ref sbi);
            if (result == 0) throw new Win32Exception();
            return sbi;
        }
        public float HScrollValue
        {
            get
            {
                SCROLLBARINFO sbi = GetSbi(OBJID.HSCROLL);
                if (sbi.rgstate[0] != 0)
                {
                    return float.NaN;
                }
                int thumbLen = sbi.xyThumbBottom - sbi.xyThumbTop;
                int rest = sbi.rcScrollBar.Right - sbi.rcScrollBar.Left - 2 * sbi.dxyLineButton - thumbLen;
                return (float)(sbi.xyThumbTop - sbi.dxyLineButton) * 100f / (float)rest;
            }
        }
        public float VScrollValue
        {
            get
            {
                SCROLLBARINFO sbi = GetSbi(OBJID.VSCROLL);
                if (sbi.rgstate[0] != 0)
                {
                    return float.NaN;
                }
                int thumbLen = sbi.xyThumbBottom - sbi.xyThumbTop;
                int rest = sbi.rcScrollBar.Bottom - sbi.rcScrollBar.Top - 2 * sbi.dxyLineButton - thumbLen;
                return (float)(sbi.xyThumbTop - sbi.dxyLineButton) * 100f / (float)rest;
            }
        }
    }
}

Gruß Robert