<commit_before>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ExtendedControls
{
    public class DataViewScrollerPanel : Panel      // Must have a DGV and a VScroll added as children by the framework
    {
        public int ScrollBarWidth { get; set; } = 20;
        public bool VerticalScrollBarDockRight { get; set; } = true;        // true for dock right
        public Padding InternalMargin { get; set; }            // allows spacing around controls

        #region Implementation
        public DataViewScrollerPanel() : base()
        {
        }

        protected override void OnControlAdded(ControlEventArgs e ) 
        {  // as controls are added, remember them in local variables.
            if (e.Control is DataGridView)
            {
                dgv = e.Control as DataGridView;
                dgv.Scroll += DGVScroll;
                dgv.RowsAdded += DGVRowsAdded;
                dgv.RowsRemoved += DGVRowsRemoved;
                dgv.MouseWheel += DGVMWheel;
            }
            else if (e.Control is VScrollBarCustom)
            {
                vsc = e.Control as VScrollBarCustom;
                vsc.Scroll += new System.Windows.Forms.ScrollEventHandler(OnScrollBarChanged);
            }
            else
                Debug.Assert(true, "Data view Scroller Panel requires DataGridView and VScrollBarCustom to be added");
        }

        protected override void OnLayout(LayoutEventArgs levent)
        {
            base.OnLayout(levent);

            int dgvcolumnheaderheight = 0;

            Rectangle area = ClientRectangle;
            area.X += InternalMargin.Left;
            area.Y += InternalMargin.Top;
            area.Width -= InternalMargin.Left + InternalMargin.Right;
            area.Height -= InternalMargin.Top + InternalMargin.Bottom;

            if (dgv != null)                       // during designing, you may get in a situation where this code runs but these are not attached.  Fail gracefully. otherwise VS crashes
            {
                dgv.Location = new Point(area.X + ((VerticalScrollBarDockRight) ? 0 : ScrollBarWidth), area.Y);
                dgv.Size = new Size(area.Width - ScrollBarWidth, area.Height);
                dgvcolumnheaderheight = dgv.ColumnHeadersHeight;
            }

            if (vsc != null)
            {
                vsc.Location = new Point(area.X + ((VerticalScrollBarDockRight) ? (area.Width - ScrollBarWidth) : 0), area.Y+dgvcolumnheaderheight);
                vsc.Size = new Size(ScrollBarWidth, area.Height - dgvcolumnheaderheight) ;
            }

            if ( dgv != null && vsc != null )
            {
                vsc.SetValueMaximumLargeChange(dgv.FirstDisplayedScrollingRowIndex, dgv.RowCount - 1, dgv.DisplayedRowCount(false));
            }
        }

        protected void DGVRowsAdded(Object sender, DataGridViewRowsAddedEventArgs e)
        {
            Debug.Assert(vsc != null, "No Scroll bar attached");
           // Console.WriteLine("Rows Added: first:" + dgv.FirstDisplayedScrollingRowIndex + " disp:" + dgv.DisplayedRowCount(false) + " rows" + dgv.RowCount + " Added " + e.RowCount);
            vsc.SetValueMaximumLargeChange(dgv.FirstDisplayedScrollingRowIndex, dgv.RowCount - 1, dgv.DisplayedRowCount(false));
        }

        protected void DGVRowsRemoved(Object sender, DataGridViewRowsRemovedEventArgs e)
        {
            Debug.Assert(vsc != null, "No Scroll bar attached");
          //  Console.WriteLine("Rows Removed: first:" + dgv.FirstDisplayedScrollingRowIndex + " disp:" + dgv.DisplayedRowCount(false) + " rows" + dgv.RowCount +  " Removed " + e.RowCount);
            vsc.SetValueMaximumLargeChange(dgv.FirstDisplayedScrollingRowIndex, dgv.RowCount - 1, dgv.DisplayedRowCount(false));
        }

        protected virtual void DGVMWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta > 0)
                vsc.ValueLimited--;                 // control takes care of end limits..
            else
                vsc.ValueLimited++;                 // end is UserLimit, not maximum

            if ( vsc.Value >= 0 )                   // we may have a situation where the scroll bar is off and value is -1.. only set if to a good value.
                dgv.FirstDisplayedScrollingRowIndex = vsc.Value;
        }

        protected void DGVScroll(Object sender, ScrollEventArgs e)
        {
            Debug.Assert(vsc != null, "No Scroll bar attached");
//            Console.WriteLine("DGV Scroll: first:" + dgv.FirstDisplayedScrollingRowIndex + " disp:" + dgv.DisplayedRowCount(false) + " rows" + dgv.RowCount);
            vsc.SetValueMaximumLargeChange(dgv.FirstDisplayedScrollingRowIndex, dgv.RowCount - 1, dgv.DisplayedRowCount(false));
        }

        protected virtual void OnScrollBarChanged(object sender, ScrollEventArgs e)
        {
            Debug.Assert(dgv != null, "No Data view attached");
            //            Console.WriteLine("VSC Scroll: first:" + dgv.FirstDisplayedScrollingRowIndex + " disp:" + dgv.DisplayedRowCount(false) + " rows" + dgv.RowCount);
            dgv.FirstDisplayedScrollingRowIndex = vsc.Value;
        }


        #endregion

        #region Variables

        DataGridView dgv;
        VScrollBarCustom vsc;

        #endregion
    }
}<commit_msg>Fix DGV Scroller panel for hidden items<commit_after>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ExtendedControls
{
    public class DataViewScrollerPanel : Panel      // Must have a DGV and a VScroll added as children by the framework
    {
        public int ScrollBarWidth { get; set; } = 20;
        public bool VerticalScrollBarDockRight { get; set; } = true;        // true for dock right
        public Padding InternalMargin { get; set; }            // allows spacing around controls

        #region Implementation
        public DataViewScrollerPanel() : base()
        {
        }

        protected override void OnControlAdded(ControlEventArgs e ) 
        {  // as controls are added, remember them in local variables.
            if (e.Control is DataGridView)
            {
                dgv = e.Control as DataGridView;
                dgv.Scroll += DGVScroll;
                dgv.RowsAdded += DGVRowsAdded;
                dgv.RowsRemoved += DGVRowsRemoved;
                dgv.MouseWheel += DGVMWheel;
            }
            else if (e.Control is VScrollBarCustom)
            {
                vsc = e.Control as VScrollBarCustom;
                vsc.Scroll += new System.Windows.Forms.ScrollEventHandler(OnScrollBarChanged);
            }
            else
                Debug.Assert(true, "Data view Scroller Panel requires DataGridView and VScrollBarCustom to be added");
        }

        protected override void OnLayout(LayoutEventArgs levent)
        {
            base.OnLayout(levent);

            int dgvcolumnheaderheight = 0;

            Rectangle area = ClientRectangle;
            area.X += InternalMargin.Left;
            area.Y += InternalMargin.Top;
            area.Width -= InternalMargin.Left + InternalMargin.Right;
            area.Height -= InternalMargin.Top + InternalMargin.Bottom;

            if (dgv != null)                       // during designing, you may get in a situation where this code runs but these are not attached.  Fail gracefully. otherwise VS crashes
            {
                dgv.Location = new Point(area.X + ((VerticalScrollBarDockRight) ? 0 : ScrollBarWidth), area.Y);
                dgv.Size = new Size(area.Width - ScrollBarWidth, area.Height);
                dgvcolumnheaderheight = dgv.ColumnHeadersHeight;
            }

            if (vsc != null)
            {
                vsc.Location = new Point(area.X + ((VerticalScrollBarDockRight) ? (area.Width - ScrollBarWidth) : 0), area.Y+dgvcolumnheaderheight);
                vsc.Size = new Size(ScrollBarWidth, area.Height - dgvcolumnheaderheight) ;
            }

            if ( dgv != null && vsc != null )
            {
                vsc.SetValueMaximumLargeChange(dgv.FirstDisplayedScrollingRowIndex, dgv.Rows.GetRowCount(DataGridViewElementStates.Visible) - 1, dgv.DisplayedRowCount(false));
            }
        }

        protected void DGVRowsAdded(Object sender, DataGridViewRowsAddedEventArgs e)
        {
            int rows = dgv.Rows.GetRowCount(DataGridViewElementStates.Visible);
            Debug.Assert(vsc != null, "No Scroll bar attached");
            //Console.WriteLine("Rows Added: first:" + dgv.FirstDisplayedScrollingRowIndex + " disp:" + dgv.DisplayedRowCount(false) + " rows" + rows + " Added " + e.RowCount);
            vsc.SetValueMaximumLargeChange(dgv.FirstDisplayedScrollingRowIndex, rows - 1, dgv.DisplayedRowCount(false));
        }

        protected void DGVRowsRemoved(Object sender, DataGridViewRowsRemovedEventArgs e)
        {
            int rows = dgv.Rows.GetRowCount(DataGridViewElementStates.Visible);
            Debug.Assert(vsc != null, "No Scroll bar attached");
            //Console.WriteLine("Rows Removed: first:" + dgv.FirstDisplayedScrollingRowIndex + " disp:" + dgv.DisplayedRowCount(false) + " rows" + rows +  " Removed " + e.RowCount);
            vsc.SetValueMaximumLargeChange(dgv.FirstDisplayedScrollingRowIndex, rows - 1, dgv.DisplayedRowCount(false));
        }

        protected virtual void DGVMWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta > 0)
                vsc.ValueLimited--;                 // control takes care of end limits..
            else
                vsc.ValueLimited++;                 // end is UserLimit, not maximum

            SetFirstDisplayed(vsc.Value);
        }

        bool ignoredgvscroll = false;
        protected void DGVScroll(Object sender, ScrollEventArgs e)
        {
            if (ignoredgvscroll == false)
            {
                int rows = dgv.Rows.GetRowCount(DataGridViewElementStates.Visible);
                Debug.Assert(vsc != null, "No Scroll bar attached");
                //Console.WriteLine("DGV Scroll: first:" + dgv.FirstDisplayedScrollingRowIndex + " disp:" + dgv.DisplayedRowCount(false) + " rows" + rows);
                vsc.SetValueMaximumLargeChange(dgv.FirstDisplayedScrollingRowIndex, rows - 1, dgv.DisplayedRowCount(false));
            }
        }

        protected virtual void OnScrollBarChanged(object sender, ScrollEventArgs e)
        {
            Debug.Assert(dgv != null, "No Data view attached");
            int rows = dgv.Rows.GetRowCount(DataGridViewElementStates.Visible);
            //Console.WriteLine("VSC Scroll: first:" + dgv.FirstDisplayedScrollingRowIndex + " disp:" + dgv.DisplayedRowCount(false) + " rows" + rows);
            SetFirstDisplayed(vsc.Value);
        }

        private void SetFirstDisplayed(int count)                   // find first entry which is visible at this count
        {
            //Console.WriteLine("Want " + count );
            for (int rowi = 0; rowi < dgv.RowCount; rowi++)
            {
                if (dgv.Rows[rowi].Visible == true && count-- == 0)
                {
                    //Console.WriteLine("Picked " + rowi + " Scroll bar " + vsc.Value);
                    ignoredgvscroll = true;
                    dgv.FirstDisplayedScrollingRowIndex = rowi;     // don't fire the DGVScroll.. as we can get into a cycle if rows are hidden
                    ignoredgvscroll = false;
                    return;
                }
            }
        }

        public void UpdateScroll()      // call if hide/unhide cells - no call back for this
        {
            int rows = dgv.Rows.GetRowCount(DataGridViewElementStates.Visible);
            vsc.SetValueMaximumLargeChange(dgv.FirstDisplayedScrollingRowIndex, rows - 1, dgv.DisplayedRowCount(false));
        }


        #endregion

        #region Variables

        DataGridView dgv;
        VScrollBarCustom vsc;

        #endregion
    }
}
{'fraction_non_alphanumeric': 0.09040983606557378, 'fraction_numerical': 0.0020491803278688526, 'mean_word_length': 2.025291346392264, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1681348', 'n_tokens_mistral': 3464, 'n_tokens_neox': 3248, 'n_words': 798}