WPF Zoom

Una de las primeras cosas que hice cuando me explicaron el objeto VisualBrush y que me llevo bastante tiempo hacerlo fue una lupa para que cuando mueva el ratón todo lo que se vea dentro de la lupa se vea agrandado es decir la sensación de lupa.

 

Del XAMl que os voy a poner ahora fijaros solamente en el objeto VisualBrush, el otro XAML es para hacer la lupa

 

<Canvas Name="magnifierCanvas" IsHitTestVisible="False">
        <Line StrokeThickness="30" X1="200" Y1="200" X2="300" Y2="300">
            <Line.Stroke>
                <LinearGradientBrush StartPoint="0.78786,1" EndPoint="1,0.78786">
                    <GradientStop Offset="0" Color="DarkGreen" />
                    <GradientStop Offset="0.9" Color="LightGreen" />
                    <GradientStop Offset="1" Color="Green" />
                </LinearGradientBrush>
            </Line.Stroke>
        </Line>
        <Ellipse Width="250" Height="250" Fill="White" />
        <Ellipse Width="250" Height="250" Name="magnifierEllipse" StrokeThickness="4">
            <Ellipse.Fill>
                <VisualBrush ViewboxUnits="Absolute" Viewbox="0,0,50,50"
                         ViewportUnits="RelativeToBoundingBox" Viewport="0,0,1,1" />
            </Ellipse.Fill>
            <Ellipse.Stroke>
            	<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
            		<GradientStop Color="#FF555555" Offset="0"/>
            		<GradientStop Color="#FFEEEEEE" Offset="1"/>
            	</LinearGradientBrush>
            </Ellipse.Stroke>
        </Ellipse>
        <Ellipse Canvas.Left="2" Canvas.Top="2" StrokeThickness="4" Width="246" Height="246">
            <Ellipse.Stroke>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <GradientStop Offset="0" Color="#555" />
                    <GradientStop Offset="1" Color="#EEE" />
                </LinearGradientBrush>
            </Ellipse.Stroke>

        </Ellipse>
    </Canvas>
 
 

Viewbox y Viewport son dos propiedades de ImageBursh, DrawingBrush, TileBrush and VisualBrush elements in Windows Presentation Foundation.

Estos dos atributos te permiten recortar las imágenes y figuras y ponerlas escaladas. Viewbox representa un área en la imagen original o el dibujo que queremos mostrar en nuestra aplicación. ViewPort representa el área en nuestra aplicación donde vamos a mostrar la imagen del ViewBox. ViewboxUnits determina que si los valores son relativos al Viewbox (RelativeToBoundingBox) o absolutos  (Absolute).

Para utilizar este control lo que hacemos es que en su evento Loaded

 if (Visibility == Visibility.Visible)
            {
                window = Helper.FindAncestorOrSelf<Window>(this);
                if (window != null)
                {
                    window.PreviewMouseMove += new MouseEventHandler(window_PreviewMouseMove);
                    VisualBrush b = (VisualBrush)magnifierEllipse.Fill;
                    b.Visual = (Canvas)window.FindName("canMainContent");
                }
            }
 

Miro a ver si esta dentro de un objeto Window y si esta le asocio el evnto PreviewMouseMove y el objeto VisualBrush del control asignándole un objeto de mi ventana que se llama canMainContent, que es el obejto que quiero ampliar.

En el evento PreviewMoueseMove

 void window_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            VisualBrush b = (VisualBrush)magnifierEllipse.Fill;
            Point pos = e.MouseDevice.GetPosition(window);
            Rect viewBox = b.Viewbox;
            double xoffset = viewBox.Width / 2.0;
            double yoffset = viewBox.Height / 2.0;
            viewBox.X = pos.X - xoffset;
            viewBox.Y = pos.Y - yoffset;
            viewBox.Width = 150.0;
            viewBox.Height = 150.0;
            b.Viewbox = viewBox;
            Canvas.SetLeft(this, pos.X - magnifierEllipse.Width / 2);
            Canvas.SetTop(this, pos.Y - magnifierEllipse.Height / 2);
        }

Recojo el área alrededor del ratón para ampliarlo en el VisualBrush definido.

Al a probarlo

5 comentarios sobre “WPF Zoom”

  1. Hola Cesar,
    Helper sin lugar a dudas es una clase propia donde almacena funcionalidades de uso común, como la usada en este ejemplo.
    Helper.FindAncestorOrSelf(T param) no es más que un metodo que usa VisualTreeHelper.FindAncestor para recorrer el arbol visual en busca del tipo que se le pase como parámetro. En el ejemplo de Oskar puedes sustituir esa línea de código por esta otra:
    windows = App.Current.MainWindow;
    en el caso de que el control (Oskar ha debido crear un UserControl de lupa) se encuentre dentro de la ventana principal de la aplicación.
    Esto te puede ayudar a probar el código de Oskar.
    Recuerda introducir en tu ventana principal un Panel Canvas con el nombre «canMainContent» y algo dentro para que el control de lupa pueda funcionar correctamente.
    Un saludo,

    Cristian

  2. Cristian tiene en todo su comentario razón. Helper es una clase donde voy metiendo todas las funciones comunes a todos los controles de usuario.
    FindAncestor sirve para recorrer el arbol visual que lo explique en un post anterior.
    Se puede sustituir la función por la que dice cristian windows = App.Current.MainWindow;
    Ahora estoy de vacaciones y castigado sin Internet pero despues pondre el código

  3. Cierto Oskar 😉
    Después de responder me di cuenta de que tenias el código en el post anterior.
    Muy buen trabajo el de tu blog, enhorabuena!!!
    Y felices vacaciones…
    Saludos

Responder a anonymous Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *