WebHU - Programozási kérdések és válaszok

.net görgetősáv automatikus görgetési probléma

Egy olyan alkalmazást írok .net-ben, amely az automatikus görgetést használja egy párbeszédpanel elrendezéséhez. Úgy tűnik, hogy amikor átméretezem az ablakot úgy, hogy a függőleges görgetősávok megjelenjenek, automatikusan megjelenik a vízszintes görgetősáv is. Közelről nézve a második görgetősáv lehetővé teszi, hogy 16 képponttal (a másik görgetősáv szélességével) görgessem az ablakot. Tehát úgy tűnik, hogy a Windows úgy gondolja, hogy szükségem van egy olyan ügyfélterületre, amely legalább olyan széles, mint a függőleges görgetősáv megjelenése előtt.

Ha most átméretezem az ablakot 16 képponttal szélesebbre (hogy az ablakom olyan széles legyen, mint a görgetősáv megjelenése előtt), a görgetősáv eltűnik. Ha visszaméretezem a régire, akkor távol marad.

Szóval nekem úgy tűnik, hogy van egy hiba a rendszerben, ahol a minimális szélesség valahogy ragadós, de az ablak méretének növelése és lekicsinyítése (egérrel és a görgetősávokhoz kapcsolódó API-k simítása nélkül) törli a feltételt

Tud valaki valamilyen megoldást, vagy csináljak valamit, hogy megzavarjam a Windowst?

27.09.2010

  • Én is belefutottam már ebbe; ráakadt a kérdésére a Google-on keresztül. Szokásos megoldásom az volt, hogy a függőleges görgetősáv szélességéhez igazítottam az elrendezésemet (amire lentebb már válaszolt). 02.12.2010

Válaszok:


1

Igen, azt hiszem, már helyesen diagnosztizálta a problémát. Csúnya mellékhatása annak, ha mondjuk megjelenik a függőleges görgetősáv, és helyet igényel, így a rendelkezésre álló ügyfélterület kisebb. Túl kicsi ahhoz, hogy elférjen a kezelőszervek között, így a vízszintes görgetősáv is megjelenik. Valójában bi-stabil, a vízszintes sáv bizonyos esetekben be- és kikapcsolhat.

Ennek a hatásnak a elkerülése érdekében az elrendezési motornak többször át kell haladnia az elrendezésen, és kezelnie kell a változó ügyfélterületet. Ez azonban csak egy passzot tesz lehetővé. Ami bölcsen hangzik, ez egy potenciálisan véget nem érő hurok lehet. Nem tudok megfelelő megoldást erre. A felhasználó valószínűleg csak akkora méretre fogja átméretezni az ablakot, hogy megszabaduljon legalább az egyik görgetősávtól.

27.09.2010
  • Nos, az xnview-n néztem, hogy mit szeretnék csinálni, és az xnview-nak nagyon jól sikerült a viselkedése. De gyanítom, hogy nem használták az automatikus görgetés funkciót. De az automatikus görgetés nagyon praktikus, kár, hogy nem működik megfelelően. Kár, hogy a Microsoft nem tudta helyesen csinálni. csalódás, hogy a Microsoft nem tette meg. 30.09.2010
  • Nem biztos benne, hogy ez mit jelent. De igen, ez nem fog rosszul menni, ha az automatikus görgetést nem támogatja a könyvtár. Ha csak az ablakoknak lenne a görgetősávja kívül az ablakon, soha nem lett volna probléma. Mindazonáltal nagyon tetszett, hogy megpróbálták működni. 30.09.2010

  • 2

    Ez a Windows ismert hibája – itt

    A legjobb megoldás a probléma megoldására, ha a táblázat elrendezési paneljét automatikusan egy másik panelbe helyezzük, amely a fő űrlaphoz van rögzítve, és az autoscroll = true beállítással van beállítva.

    Így már nem a táblázatelrendezés panelt használja a görgetéshez, ami hibás, hanem a panelt használja a görgetéshez, és a táblázatelrendezés panel a panelen belül van

    10.02.2011

    3

    Nem vettem észre pontosan az általad leírt viselkedést, de olyan helyzetekbe ütköztem, amikor a függőleges görgetősáv megjelenése szükségessé teszi a vízszintes görgetősáv használatát.

    Beállíthatja a panel tartalmát úgy, hogy lehetővé tegye a görgetősáv szélességét, például ha van egy ListBox a Panel-ban:

    listBox1.Width = panel2.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth;
    

    HTH

    27.09.2010

    4

    Most találkoztam ezzel a problémával. Az általam használt javítás az volt, hogy a Scrollable értéket false-ra, majd true-ra állítottam. Íme egy példa egy ListView Resize eseménnyel:

    private void myListView_Resize(object sender, EventArgs e)
    {
     this.SuspendLayout();
    
     //Code to do various resizing stuff
    
     //Force Scrollbar Recalculation
     myListView.Scrollable = false;
     myListView.Scrollable = true;
     this.ResumeLayout(false);
     this.PerformLayout();
    }
    

    Ha a Scrollable nem mindig igaz, akkor az újraszámítást feltételessé teheti.

    01.10.2010
  • Ez az, amit végül én is csináltam, de olyan problémákba ütköztem, hogy az egyik görgetősáv addig maradt, amíg mindkettő el nem tűnt. Ami a problémám természete. Végül felhagytam azzal, hogy a Windows-t rávegyem a megfelelő dologra, és abbahagytam az automatikus görgetés funkció használatát. 19.11.2010

  • 5

    Annak ellenére, hogy ez régi kérdés, még mindig probléma a .NET 4-ben. Miután annyit olvastam, amennyit csak találtam a témában, a megoldások kombinációját egy segítő osztályba gyűjtöttem.

    Először is, itt van az eredmény, amiért forgatok... Van egy panelem, amely különféle vezérlőket tartalmaz. A gyermekvezérlők és méretük a felhasználói tevékenységtől függően változhat. Azt szeretném, hogy a panel vízszintesen átméretezzen, hogy soha ne legyen vízszintes görgetősáv, de ha függőlegesen nincs elég hely, akkor a függőleges görgetősáv jelenjen meg. Továbbá a függőleges görgetősáv nem takarja el egyetlen gyermekem vezérlőelemét sem, amikor megjelenik, és nem akarok rést hagyni számára, amikor nincs rá szükség.

    A két "hiba", amelyet a segítő osztályom megpróbál kijavítani, az első, hogy soha nem jeleníti meg a vízszintes görgetősávot, másodszor pedig, amikor megjelenik a függőleges görgetősáv, a panel szélessége automatikusan megnövekszik, hogy alkalmazkodjon hozzá.

    Feltételezem, hogy a panel Automatikus méretre és AutoScrollra van állítva, és a gyermekvezérlők is AutoSize-re vannak állítva.

    A megoldás

    A segítő osztály csatlakozik a panelhez (a Paint és a SizeChanged események kezelésével), és két dolgot csinál. Először is letiltja a vízszintes görgetősávot. Ez nem olyan egyszerű, mint amilyennek hangzik, és megtaláltam a megoldást erre a problémára: Kbv Subrahmanyam vízszintes görgetősáv válasza. Másodszor, válaszul a Paint és SizeChanged eseményekre, valamint egy háttéridőzítőre, ellenőrzi, hogy a függőleges görgetősáv Visible tulajdonsága megváltozott-e. Ha igen, a helper osztály megváltoztatja a panel Right Padding tulajdonságát, hogy hozzáadja vagy eltávolítsa a görgetősáv által igényelt extra helyet. A különböző panelesemények és az időzítő használata azért szükséges, mert a .NET nincs eseményeket tesz közzé a görgetősávon (nagy tervezési hiba, IMHO).

    Az utolsó pont az, hogy a SizeChanged esemény kezelése közben nem tehet semmit, ami megváltoztatná a panel méretét. Rossz dolgok (tm) történnek, ha megteszed. Tehát, ha módosítanom kell a kitöltést egy SizeChanged esemény miatt, a módosítást későbbre ütemezem.

    Amúgy itt van a helper osztály kódja. Feltételezi, hogy rendelkezik az összes megfelelő "using" utasítással, beleértve a System.Threading ...

    /// <summary>
    /// This class is intended to beat the AutoSize and AutoScroll features into submission!
    /// 
    /// Or, at least getting them to work the way I want them to (which may not be the way 
    /// others think they should work).
    /// 
    /// This class will force a panel that has AutoSize enabled to actually increase its
    /// width as appropriate when the AutoScroll Vertical scroll bar becomes visible.
    /// I like this better than attempting to 'reserve' space for the Vertical scroll bar,
    /// which wastes space when the scroll bar is not needed, and leaves ugly gaps in
    /// your user interface.
    /// </summary>
    public class AutoScrollFixer
    {
        /// <summary>
        /// This is the panel we are 'fixing'
        /// </summary>
        private Panel _panel;
    
        /// <summary>
        /// This field keeps track of the original value for
        /// the right padding property of the panel.
        /// </summary>
        private int _originalRightPadding = 0;
    
        /// <summary>
        /// We use this flag to prevent recursion problems.
        /// </summary>
        private bool _adjusting = false;
    
        /// <summary>
        /// This flag keeps track of the last known state of the scroll bar.
        /// </summary>
        private bool _lastScrollBarVisible = false;
    
        /// <summary>
        /// We use a timer to check the scroll bar state every so often.
        /// This is necessary since .NET (in another stunning piece of
        /// architecture from Microsoft) provides absolutely no events
        /// attached to the scroll bars of a panel.
        /// </summary>
        private System.Windows.Forms.Timer _timer = new System.Windows.Forms.Timer();
    
        /// <summary>
        /// Construct an AutoScrollFixer and attach it to the provided panel.
        /// Once created, there is no particular reason to keep a reference 
        /// to the AutoScrollFixer in your code.  It will silently do its thing
        /// in the background.
        /// </summary>
        /// <param name="panel"></param>
        public AutoScrollFixer(Panel panel)
        {
            _panel = panel;
            _originalRightPadding = panel.Padding.Right;
    
            EnableVerticalAutoscroll(_panel);
            _lastScrollBarVisible = _panel.VerticalScroll.Visible;
    
            _panel.Paint += (s, a) =>
            {
                AdjustForVerticalScrollbar();
            };
    
            _panel.SizeChanged += (s, a) =>
            {
                //
                //  We can't do something that changes the size while handling
                //  a size change.  So, if an adjustment is needed, we will
                //  schedule it for later.
                //
                if (_lastScrollBarVisible != _panel.VerticalScroll.Visible)
                {
                    AdjustLater();
                }
            };
    
            _timer.Tick += (s, a) =>
            {
                //
                //  Sadly, the combination of the Paint event and the SizeChanged event
                //  is NOT enough to guarantee that we will catch a change in the
                //  scroll bar status.  So, as a last ditch effort, we will check
                //  for a status change every 500 mSecs.  Yup, this is a hack!
                //
                AdjustForVerticalScrollbar();
            };
    
            _timer.Interval = 500;
            _timer.Start();
        }
    
    
        /// <summary>
        /// Enables AutoScroll, but without the Horizontal Scroll bar.
        /// Only the Vertical Scroll bar will become visible when necessary
        /// 
        /// This method is based on this StackOverflow answer ...
        /// https://stackoverflow.com/a/28583501/2175233
        /// </summary>
        /// <param name="panel"></param>
        public static void EnableVerticalAutoscroll( Panel panel )
        {
            panel.AutoScroll = false;
            panel.HorizontalScroll.Enabled = false;
            panel.HorizontalScroll.Visible = false;
            panel.HorizontalScroll.Maximum = 0;
            panel.AutoScroll = true;
        }
    
    
        /// <summary>
        /// Queue AdjustForVerticalScrollbar to run on the GUI thread after the current
        /// event has been handled.
        /// </summary>
        private void AdjustLater()
        {
            ThreadPool.QueueUserWorkItem((t) => 
            {
                Thread.Sleep(200);
                _panel.BeginInvoke((Action)(() =>
                {
                    AdjustForVerticalScrollbar();
                }));
            });
        }
    
    
        /// <summary>
        /// This is where the real work gets done.  When this method is called, we will
        /// simply set the right side padding on the panel to make room for the
        /// scroll bar if it is being displayed, or reset the padding value to 
        /// its original value if not.
        /// </summary>
        private void AdjustForVerticalScrollbar()
        {
            if (!_adjusting)
            {
                try
                {
                    _adjusting = true;
    
                    if (_lastScrollBarVisible != _panel.VerticalScroll.Visible)
                    {
                        _lastScrollBarVisible = _panel.VerticalScroll.Visible;
    
                        Padding p = _panel.Padding;
                        p.Right = _lastScrollBarVisible ? _originalRightPadding + System.Windows.Forms.SystemInformation.VerticalScrollBarWidth + 2 : _originalRightPadding;
                        _panel.Padding = p;
                        _panel.PerformLayout();
                    }
                }
    
                finally
                {
                    _adjusting = false;
                }
            }
        }
    }
    
    28.01.2016
    Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..