@ 조엘
고마워요! 나는 그것을 가지고있다, 반사체로부터의 작은 도움과 함께하기가 그렇게 어렵지 않았다. 최적화 할 수있는 방법이있을 수 있지만 이것이 내가 시작해야 할 것입니다. FlowLayoutPanel에서이 기능이 필요 했었지만 ScrollableControl에서 상속 한 모든 기능을 사용할 수 있습니다.
편집 : @Joel B Fant가 내가 대리자를 제거하지 않고 타이머 개체를 무기한으로 유지한다는 것을 지적하여 몇 가지를 변경했습니다. 대리자를 EventHandler 개체에 할당하여 그 자체 내에서 제거 할 수 있도록함으로써 이러한 우려를 해소했다고 생각합니다.
using System;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
public class AnimatedScrollFlowLayoutPanel : FlowLayoutPanel
{
public new void ScrollControlIntoView(Control activeControl)
{
if (((this.IsDescendant(activeControl) && this.AutoScroll) &&
(this.HScroll || this.VScroll)) && (((activeControl != null) &&
(ClientRectangle.Width > 0)) && (ClientRectangle.Height > 0)))
{
Point point = this.ScrollToControl(activeControl);
int x = DisplayRectangle.X, y = DisplayRectangle.Y;
bool scrollUp = x < point.Y;
bool scrollLeft = y < point.X;
Timer timer = new Timer();
EventHandler tickHandler = null;
tickHandler = delegate {
int jumpInterval = ClientRectangle.Height/10;
if (x != point.X || y != point.Y)
{
y = scrollUp ?
Math.Min(point.Y, y + jumpInterval) :
Math.Max(point.Y, y - jumpInterval);
x = scrollLeft ?
Math.Min(point.X, x + jumpInterval) :
Math.Max(point.X, x - jumpInterval);
this.SetScrollState(8, false);
this.SetDisplayRectLocation(x, y);
this.SyncScrollbars(true);
}
else
{
timer.Stop();
timer.Tick -= tickHandler;
}
};
timer.Tick += tickHandler;
timer.Interval = 5;
timer.Start();
}
}
internal bool IsDescendant(Control descendant)
{
MethodInfo isDescendantMethod = typeof(Control).GetMethod(
"IsDescendant", BindingFlags.NonPublic | BindingFlags.Instance);
return (bool)isDescendantMethod.Invoke(this, new object[] { descendant });
}
private void SyncScrollbars(bool autoScroll)
{
MethodInfo syncScrollbarsMethod = typeof(ScrollableControl).GetMethod(
"SyncScrollbars", BindingFlags.NonPublic | BindingFlags.Instance);
syncScrollbarsMethod.Invoke(this, new object[] { autoScroll });
}
}
큰 문제가 하나 있습니다. 델리게이트를 틱 이벤트에 계속 추가하고 작업이 끝나면 제거하지 마십시오. 한 번에 Tick 이벤트에서 1 명의 대리인 만 가질 수 있도록 약간의 재 설계가 필요합니다. –
이러한 재 설계에는 아마도 익명의 대리인을 사용하지 않아도됩니다. 이벤트에서 익명의 대리자를 제거 할 수 없습니다. –
의견을 보내 주셔서 감사합니다. 나는 확실히 이해하고 있는지 잘 모르겠다. 만약 익명의 위임자를 사용하지 않는 것으로 변경했다면 위임자를 추가하는 코드는 다음과 같다. timer.Tick + = 새로운 EventHandler (timer_Tick) 이벤트에서 대의원을 제거해야합니까? –