ASP.NET Weblogs

Welcome to ASP.NET Weblogs Sign in | Join | Help
in Search

Josh Schwartzberg high-fives the CLR

and plays with his shiny golden hammer....

November 2009 - Posts

  • Silverlight BringIntoView() extension method (with OnGotFocus behavior)

    It all started because I couldn't find a way to automatically scroll any element into view in Silverlight (a feature
    that exists in WPF).  I take that back, I could get the job done with a ListBox's ScrollIntoView(ListBoxItem item)
    method, but I hardly wanted everything on my screen to be wrapped as a ListBoxItem; it feels as dirty as it sounds.  

    Anyways, here is the code.

    /* Extension Methods */
    public static class FrameworkElementExtensions
    {
        private const int ScrollPadding = 10;
    
        public static void BringIntoView(this FrameworkElement frameworkElement)
        {
            var parent = VisualTreeHelper.GetParent(frameworkElement);
            while(parent != null)
            {
                parent = VisualTreeHelper.GetParent(parent);
                var scrollViewer = parent as ScrollViewer;
                if(scrollViewer != null)
                {
                    frameworkElement.BringIntoViewForScrollViewer(scrollViewer);
                    break;
                }
            }
        }
    
        public static void BringIntoViewForScrollViewer(this FrameworkElement frameworkElement, ScrollViewer scrollViewer)
        {
            var transform = frameworkElement.TransformToVisual(scrollViewer);
            var positionInScrollViewer = transform.Transform(new Point(0, 0));
    
            if (positionInScrollViewer.Y < 0 || positionInScrollViewer.Y > scrollViewer.ViewportHeight)
                scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + positionInScrollViewer.Y - ScrollPadding);
        }
    } 

     

    Bonus Behavior! (Behaviors?!? Here is an Introduction).
    This behavior was created ensure that as a user tabs through the screen, scrolling automatically takes place.

    Note: If you want to use behaviors in Silverlight, install the Blend 3 SDK and reference
    Microsoft.Expression.Interactions.dll

    /* Behavior class  */
    public class BringIntoViewOnFocusBehavior : Behavior<FrameworkElement>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.GotFocus += OnGotFocus;
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.GotFocus -= OnGotFocus;
        }
    
        private void OnGotFocus(object sender, RoutedEventArgs e1)
        {
            AssociatedObject.BringIntoView();
        }        
    }

     

    <!-- XAML usage of custom behavior -->
    <UserControl 
        xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
        xmlns:behaviors="clr-namespace:YourNamespaceToBehaviors.Behaviors">        
        <StackPanel>
            <TextBox>
                <interactivity:Interaction.Behaviors>
                    <behaviors:BringIntoViewOnFocusBehavior />
                </interactivity:Interaction.Behaviors>
            </TextBox>
        </StackPanel>    
    </UserControl>
More Posts