locked
how to build a magnifier in wpf ? RRS feed

  • Question

  • Dear all,

    In one of my project i am displaying a set of article and drawings which can be easyly seen by normal people I would say bit no so easy with people with glasses or low vision. For that I would like to build a Magnifier circle that I can move over the arcticle and all the area below the space occupied by the rectangle will zoom in with a default value. Then if I rotate the circle counter clockwise, I can zoom in deeper.

    Any tips how to perform such magnifier ?

    regards

    serge


    Your knowledge is enhanced by that of others.
    Friday, November 11, 2011 12:08 AM

Answers

  • Hi Serge,

    VisualBrush allows you to paint something with the current look of a Visual.

    So basically you can use it to paint the circle with the current look of a Visual.

    Viewbox property allows you to specify on which particular part of that Visual you want to paint with.

    The following is a very simple sample to demonstrate it. The zooming ratio is hard coded to 1/0.3 in this sample.

    <Window x:Class="WPFSandBox.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="500" Width="700">
        <Grid>
            <StackPanel Background="Transparent" Name="ContentPanel" MouseMove="ContentPanel_MouseMove" MouseEnter="ContentPanel_MouseEnter" MouseLeave="ContentPanel_MouseLeave">
                <TextBlock Text="SomeText"/>
                <Button Content="This is a Button"/>
                <TextBlock Text="SomeText"/>
                <Button Content="This is a Button"/>
                <TextBlock Text="SomeText"/>
                <Button Content="This is a Button"/>
                <TextBlock Text="SomeText"/>
                <Button Content="This is a Button"/>
                <TextBlock Text="SomeText"/>
            </StackPanel>
            <Canvas IsHitTestVisible="False" Name="MagnifierPanel">
                <Ellipse Stroke="LightBlue" Name="MagnifierCircle" Height="100" Width="100">
                    <Ellipse.Fill>
                        <VisualBrush x:Name="MagnifierBrush"  Visual="{Binding ElementName=ContentPanel}" ViewboxUnits="Absolute"/>
                    </Ellipse.Fill>
                </Ellipse>
            </Canvas>
        </Grid>
    </Window>
    

     

        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private double _factor = 0.3;
    
            private void ContentPanel_MouseMove(object sender, MouseEventArgs e)
            {
                Point center = e.GetPosition(ContentPanel);
                double length = MagnifierCircle.ActualWidth * _factor;
                double radius = length/2;
                Rect viewboxRect = new Rect(center.X - radius, center.Y - radius, length, length);
                MagnifierBrush.Viewbox = viewboxRect;
    
                MagnifierCircle.SetValue(Canvas.LeftProperty, center.X - MagnifierCircle.ActualWidth/2);
                MagnifierCircle.SetValue(Canvas.TopProperty, center.Y - MagnifierCircle.ActualHeight/2);
    
            }
    
            private void ContentPanel_MouseEnter(object sender, MouseEventArgs e)
            {
                MagnifierCircle.Visibility = Visibility.Visible;
            }
    
            private void ContentPanel_MouseLeave(object sender, MouseEventArgs e)
            {
                MagnifierCircle.Visibility = Visibility.Hidden;
            }
        }
    

     

    Best regards,

     


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Min Zhu Monday, November 21, 2011 2:03 AM
    Friday, November 11, 2011 9:03 AM

  • Gaurav Khanna | Microsoft VB.NET MVP
    • Marked as answer by Min Zhu Monday, November 21, 2011 2:03 AM
    Friday, November 11, 2011 10:45 AM

All replies

  • Hi Serge,

    I suggest to use a VisualBrush to render the original visual on the Magnifier rectangle. You can use VisualBrush's Viewbox and Viewport properties to zoom in and out.

    If anything is unclear, please feel free to let me know.

    Best regards,


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, November 11, 2011 2:35 AM
  • Hello Min Zhu,

    Sorry did not catch the idea, never use Visual Brush, not familar with view port propertie and no idea how to combine those in order to reach what I need.
    First sory its a circle shape which will be use. I need to place that circle on the application and inside that circle gets the bottom object contains my article zoomed.

    I will appreciate a look sample on this. I have already look on net for magnifer sample but do not fit my goal. if you can help that will be kind

    I have find this sample : http://www.interact-sw.co.uk/iangblog/2007/03/28/wpfmagnifyupdate but it does not use the viewport and could not catch where the zoom ratio is set 

    regards

    serge


    Your knowledge is enhanced by that of others.
    Friday, November 11, 2011 8:09 AM
  • Hi Serge,

    VisualBrush allows you to paint something with the current look of a Visual.

    So basically you can use it to paint the circle with the current look of a Visual.

    Viewbox property allows you to specify on which particular part of that Visual you want to paint with.

    The following is a very simple sample to demonstrate it. The zooming ratio is hard coded to 1/0.3 in this sample.

    <Window x:Class="WPFSandBox.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="500" Width="700">
        <Grid>
            <StackPanel Background="Transparent" Name="ContentPanel" MouseMove="ContentPanel_MouseMove" MouseEnter="ContentPanel_MouseEnter" MouseLeave="ContentPanel_MouseLeave">
                <TextBlock Text="SomeText"/>
                <Button Content="This is a Button"/>
                <TextBlock Text="SomeText"/>
                <Button Content="This is a Button"/>
                <TextBlock Text="SomeText"/>
                <Button Content="This is a Button"/>
                <TextBlock Text="SomeText"/>
                <Button Content="This is a Button"/>
                <TextBlock Text="SomeText"/>
            </StackPanel>
            <Canvas IsHitTestVisible="False" Name="MagnifierPanel">
                <Ellipse Stroke="LightBlue" Name="MagnifierCircle" Height="100" Width="100">
                    <Ellipse.Fill>
                        <VisualBrush x:Name="MagnifierBrush"  Visual="{Binding ElementName=ContentPanel}" ViewboxUnits="Absolute"/>
                    </Ellipse.Fill>
                </Ellipse>
            </Canvas>
        </Grid>
    </Window>
    

     

        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private double _factor = 0.3;
    
            private void ContentPanel_MouseMove(object sender, MouseEventArgs e)
            {
                Point center = e.GetPosition(ContentPanel);
                double length = MagnifierCircle.ActualWidth * _factor;
                double radius = length/2;
                Rect viewboxRect = new Rect(center.X - radius, center.Y - radius, length, length);
                MagnifierBrush.Viewbox = viewboxRect;
    
                MagnifierCircle.SetValue(Canvas.LeftProperty, center.X - MagnifierCircle.ActualWidth/2);
                MagnifierCircle.SetValue(Canvas.TopProperty, center.Y - MagnifierCircle.ActualHeight/2);
    
            }
    
            private void ContentPanel_MouseEnter(object sender, MouseEventArgs e)
            {
                MagnifierCircle.Visibility = Visibility.Visible;
            }
    
            private void ContentPanel_MouseLeave(object sender, MouseEventArgs e)
            {
                MagnifierCircle.Visibility = Visibility.Hidden;
            }
        }
    

     

    Best regards,

     


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Min Zhu Monday, November 21, 2011 2:03 AM
    Friday, November 11, 2011 9:03 AM
  • Th aks , I have test you sample but one confuse point.

    Sorry for basic question but..

    What is the use of this code :

     

    double length = MagnifierCircle.ActualWidth * _factor;
                double radius = length / 2;
                Rect viewboxRect = new Rect(center.X - radius, center.Y - radius, length, length);
    

    I understant that it is for defining the view rectabgle but could not catch the logic on the way to build that viewbox 

    For exemple in order to catch the idea I have set this _factor variale to a value of 10. Then If I start the app I can see a relly small representation of the panel while I am not on top of it but position the magnifier on the bottom of the grid ??? 


    Your knowledge is enhanced by that of others.
    Friday, November 11, 2011 10:13 AM

  • Gaurav Khanna | Microsoft VB.NET MVP
    • Marked as answer by Min Zhu Monday, November 21, 2011 2:03 AM
    Friday, November 11, 2011 10:45 AM
  • You probably already considered this, but there's also the zero code option.

    Click start

    Type Magnifier

     

    There are options you can set to magnify portions or all the screen.

    Friday, November 11, 2011 11:33 AM
  • Hi Serge Calderara,

    In this sample, if you want to zoom in 10*, you can set _factor to 0.1 .

    When _factor is 1, it simply shows the same area beneath the MagnifierCircle.

    When _factor is smaller than 1, it uses a smaller Viewbox, so a smaller area is displayed in the MagnifierCircle. This gives us the zooming effects.

    If you still have any questions or concerns about this issue, please feel free to let me know.

    Best regards,


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Monday, November 14, 2011 2:31 AM
  • Hi Serge,

    Just checking in to see if the information was helpful. Please let us know if you would like further assistance.

    Have a great day!


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Wednesday, November 16, 2011 4:59 AM