/// <summary> /// Initializes a new instance of the BallonToolTip class. /// </summary> public BallonToolTip() { m_window = new NativeToolTipWindow(this); m_controls = new Hashtable(); m_addedList = new ArrayList(); m_style = ToolTipStyle.Balloon; }
/// <summary> /// Handle vertical scroll to make it smoother /// </summary> /// <remarks>The default scrolling increments are quite small and the frequent redraws cause a messy /// display when the thumb is dragged. By handling it ourselves, we can initialize and bind the rows /// before they are displayed and can also control the increments to provide a smoother scroll with a /// cleaner visual appearance.</remarks> /// <param name="m">The vertical scroll message parameters</param> private void HandleVerticalScroll(ref Message m) { TemplateControl tc; DataList owner = (DataList)this.Parent; Rectangle clientRect = base.ClientRectangle, displayRect = base.DisplayRectangle; int row, fillRange, maxRows, multiplier, rowHeight = owner.RowHeight, curPos = -displayRect.Y; int maxPos = -(clientRect.Height - displayRect.Height - rowHeight), scrollEvent = (int)m.WParam & 0xFFFF; switch (scrollEvent) { case 0: // Line up if (curPos <= 0) { curPos = 0; } else { curPos -= rowHeight; } break; case 1: // Line down if (curPos >= maxPos - rowHeight) { curPos = maxPos; } else { curPos += rowHeight; } break; case 2: // Page up if (curPos <= clientRect.Height) { curPos = 0; } else { curPos -= clientRect.Height; } break; case 3: // Page down if (curPos >= maxPos - clientRect.Height) { curPos = maxPos; } else { curPos += clientRect.Height; } break; case 4: // Thumb position (end tracking) case 5: // Thumb track (drag) if (scrollTip == null) { scrollTip = new NativeToolTipWindow(this); } // Round it to the nearest row start and show the position in a tool tip curPos = UnsafeNativeMethods.ScrollThumbPosition(base.Handle, 1) / rowHeight * rowHeight; scrollTip.ShowTooltip(String.Format(CultureInfo.InvariantCulture, LR.GetString("DLScrollPos"), (curPos / rowHeight) + 1, owner.RowCount)); break; case 6: // Top curPos = 0; break; case 7: // Bottom curPos = maxPos; break; case 8: // End scroll if (scrollTip != null && scrollTip.IsVisible) { scrollTip.HideTooltip(); } break; case 32767: // Custom call to scroll row into view curPos = m.LParam.ToInt32(); if (curPos < 0) { curPos = 0; } else if (curPos >= maxPos) { curPos = maxPos; } break; } // Ignore if not displaying content while scrolling and it was a thumb tracking event if (this.GetScrollState(0x10) || scrollEvent != 5) { // Initialize and bind the rows before they are displayed to smooth out the scrolling multiplier = (owner.SeparatorsVisible) ? 2 : 1; if (owner.ListManager != null && this.Controls.Count != 0) { maxRows = owner.ListManager.Count; // Get the range of visible rows row = curPos / rowHeight; fillRange = ((curPos + rowHeight + this.Height) / rowHeight) + 1; if (fillRange < maxRows) { maxRows = fillRange; } } else { row = maxRows = 0; } while (row < maxRows) { if (row * multiplier < this.Controls.Count) { tc = (TemplateControl)this.Controls[row * multiplier]; } else { tc = null; } // By waiting until the templates scroll into view, it saves some time and resources during // the initial load and only binds what is actually shown. if (tc != null && !tc.IsNewRowInternal && !tc.HasBeenBound) { if (!tc.HasBeenInitialized) { tc.InitializeTemplate(); tc.HasBeenInitialized = true; } tc.Bind(); tc.HasBeenBound = true; owner.OnItemDataBound(new DataListEventArgs(row, tc)); } row++; } // Set "user scrolled" flag and update the display rectangle this.SetScrollState(8, true); this.SetDisplayRectLocation(displayRect.X, -curPos); if (syncScrollbars != null) { syncScrollbars.Invoke(this, new object[] { this.AutoScroll }); } // Refresh the row headers if they are visible if (owner.RowHeadersVisible) { owner.Invalidate(new Rectangle(0, 0, owner.RowHeaderWidth, owner.Height), false); } } if (scrollEvent != 8) { ScrollEventArgs se = new ScrollEventArgs((ScrollEventType)scrollEvent, -displayRect.Y, curPos, ScrollOrientation.VerticalScroll); base.OnScroll(se); } }