Silverlight ScrollViewer 스크롤을 어떻게 초점을 맞추고 어린이 컨트롤을 보여줄 수 있습니까?

StackOverflow https://stackoverflow.com/questions/1225318

  •  22-07-2019
  •  | 
  •  

문제

여러 컨트롤이있는 그리드가 포함 된 스크롤 뷰어가 있습니다. 사용자는 컨트롤을 통해 탭을 할 수 있지만 결국 컨트롤을 보지 못하도록 스크롤해야합니다.

초점을 맞춘 제어가 항상 보이도록 스크롤 뷰어 스크롤을 자동으로 만들 수있는 방법이 있습니까? 실패하면, 모든 컨트롤에서 Gotfocus 이벤트를 듣지 못하고 ScrollViewer를 스크롤하여 컨트롤을 볼 수 있도록이 작업을 수행 할 수있는 방법이 있습니까?

현재 나는 Silverlight 2를 사용하고 있습니다.

도움이 되었습니까?

해결책

Silvlight 3을 사용하여 이것을 테스트했습니다. SL2에 대해 잘 모르겠습니다.

이것은 내 xaml입니다 :

<ScrollViewer Height="200" Width="200" KeyUp="ScrollViewer_KeyUp">
    <StackPanel>
        <Button Content="1" Height="20" />
        <Button Content="2" Height="20" />
        <Button Content="3" Height="20" />
        <Button Content="4" Height="20" />
        <Button Content="5" Height="20" />
        <Button Content="6" Height="20" />
        <Button Content="7" Height="20" />
        <Button Content="8" Height="20" />
        <Button Content="9" Height="20" />
    <Button Content="10" Height="20" />
        <Button Content="11" Height="20" />
        <Button Content="12" Height="20" />
        <Button Content="13" Height="20" />
        <Button Content="14" Height="20" />
        <Button Content="15" Height="20" />
        <Button Content="16" Height="20" />
        <Button Content="17" Height="20" />
        <Button Content="18" Height="20" />
        <Button Content="19" Height="20" />
        <Button Content="20" Height="20" />
    </StackPanel>
</ScrollViewer>

그리고 이것은 코드-비만입니다.

private void ScrollViewer_KeyUp(object sender, KeyEventArgs e)
{
    ScrollViewer scrollViewer = sender as ScrollViewer;
    FrameworkElement focusedElement = FocusManager.GetFocusedElement() as FrameworkElement;
    GeneralTransform focusedVisualTransform = focusedElement.TransformToVisual(scrollViewer);
    Rect rectangle = focusedVisualTransform.TransformBounds(new Rect(new Point(focusedElement.Margin.Left, focusedElement.Margin.Top), focusedElement.RenderSize));
    double newOffset = scrollViewer.VerticalOffset + (rectangle.Bottom - scrollViewer.ViewportHeight);
    scrollViewer.ScrollToVerticalOffset(newOffset);
}

내가 한 일은 버튼 #20에 도달 할 때까지 버튼 #1과 탭을 클릭하는 것이 었습니다. 그것은 나를 위해 일했다. 시도해보고 어떻게 작동하는지 알려주세요.

다른 팁

Silverlight 툴킷에는 "Scrollintoview"메소드가 포함되어 있습니다.

System.windows.controls.toolkit.dll ans에 대한 참조를 추가하십시오. 아래 코드를 사용할 수 있어야합니다.

scrollViewer.ScrollIntoView(control);

약간의 향상. 그건 그렇고 Silverlight 4의 경우 여전히이 작업을 수행해야합니다. 각 컨트롤에 대한 GotFocus 대신 ScrollViewer 자체의 GotFocus를 처리하고 한 번만 구현할 수 있습니다.

 private void _ScrollViewer_GotFocus(object sender, RoutedEventArgs e)
        {
            FrameworkElement element = e.OriginalSource as FrameworkElement;

            if (element != null)
            {
                ScrollViewer scrollViewer = sender as ScrollViewer;
                scrollViewer.ScrollToVerticalOffset(GetVerticalOffset(element, scrollViewer));
            }

        }

        private double GetVerticalOffset(FrameworkElement child, ScrollViewer scrollViewer)
        {
            // Ensure the control is scrolled into view in the ScrollViewer. 
            GeneralTransform focusedVisualTransform = child.TransformToVisual(scrollViewer);
            Point topLeft = focusedVisualTransform.Transform(new Point(child.Margin.Left, child.Margin.Top));
            Rect rectangle = new Rect(topLeft, child.RenderSize);
            double newOffset = scrollViewer.VerticalOffset + (rectangle.Bottom - scrollViewer.ViewportHeight);
            return newOffset < 0 ? 0 : newOffset; // no use returning negative offset
        }

위의 Kiril의 대답에 도움을 주면서 이것을 작동 시켰습니다. 이것의 일반적인 맥락은 응용 프로그램에 사용자 정의 가능한 양식이 있으며이 코드는 컨트롤을 양식에 렌더링하는 데 사용된다는 것입니다.

저의 일반적인 전략은 내 컨트롤을 그리드에 추가 한 다음 VisualTreeHelper를 사용하여 ScrollViewer의 모든 어린이를 찾아 각 컨트롤에 GOTFocus 이벤트 처리기를 추가하는 것이 었습니다.

컨트롤이 초점을 맞추면 VisualTreeHelper를 사용하여 다시 시각적 트리를 검색하여 ScrollViewer가 스크롤하는 그리드 인 컨트롤을 찾습니다. 그런 다음 ScrollViewer를 스크롤하여 컨트롤을 볼 수 있도록합니다.

코드는 다음과 같습니다 (Gridrender는 컨트롤이 추가되는 그리드입니다).

private void AfterFormRendered()
{
    var controls = VisualTreeHelperUtil.FindChildren<Control>(gridRender);
    foreach (var ctrl in controls)
    {
        ctrl.GotFocus += CtrlGotFocus;
    }
}

private void CtrlGotFocus(object sender, RoutedEventArgs e)
{
    var ctrl = sender as Control;
    var gridChildControl = VisualTreeHelperUtil.FindParentWithParent(ctrl, gridRender) as FrameworkElement;

    if (gridChildControl != null)
    {
        // Ensure the control is scrolled into view in the ScrollViewer.
        GeneralTransform focusedVisualTransform = gridChildControl.TransformToVisual(scrollViewer);
        Point topLeft = focusedVisualTransform.Transform(new Point(gridChildControl.Margin.Left, gridChildControl.Margin.Top));
        Rect rectangle = new Rect(topLeft, gridChildControl.RenderSize);
        double newOffset = scrollViewer.VerticalOffset + (rectangle.Bottom - scrollViewer.ViewportHeight);    

        scrollViewer.ScrollToVerticalOffset(newOffset);
    }
}

참고 : VisualTreeHelPerutil 클래스는 VisualTreeHelper 클래스에 유용한 검색 기능을 추가하는 내 자신의 클래스입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top