WPF之VistualBrush应用(制作放大镜)

1 篇文章 0 订阅
1 篇文章 0 订阅

                我们可以通过WPF的VistualBrush获取画面中某个区域内容来当做某个元素内容的来源。根据这个原理我们就可以做出一些奇特的效果,比如放大镜的制作。

                我先举个简单的利用VistualBrush的例子(文字的镜像效果)。这样更方便了解VistualBrush的原理。

               

                1.先拖一个TextBox控件 命名为textBox1。再拖一个Rectangle矩形控件(当然也可以拖拽Lable控件,给Label.Background 填充内容)。

                2.可以看到Rectangle呈现的内容就是TextBox的内容,而且是以倒影的形式显示出来。 所以接下来要做的就是给Rectangle填充TextBox的内容

              

<Rectangle Name="rectangle1" Stroke="Black" 
                      StrokeThickness="1" HorizontalAlignment="Left">
            <Rectangle.Fill>
                <VisualBrush Visual="{Binding ElementName=textBox1}">   
                 <!--获取视图来源-->
                </VisualBrush>
            </Rectangle.Fill>
</Rectangle>


                这样就完成了Rectangle的填充。  但还没有上面的镜像效果

               

                3.接下来我们将在VisualBrush 标签里用到RelativeTransform。就是将内容进行相对的转化

<VisualBrush Visual="{Binding ElementName=textBox1}"> 

     <VisualBrush.RelativeTransform> 

         <TransformGroup> 

            <ScaleTransform ScaleX="1" ScaleY="-1"/> 

            <TranslateTransform Y="1"/> 

         </TransformGroup> 

     </VisualBrush.RelativeTransform> 

</VisualBrush> 


 

                   这样就出现了一张图片的效果。  因此就更容易明白VistualBrush获取画面中某个区域内容来当做某个元素内容的来源的意思了。

 

                  同样的原理,接下来就开始利用VisualBrush制作具有放大功能的放大镜

                 

                  我们要实现的是用放大镜在某个区域里实现放大的效果

因为上述有个简单的小例子,那么接下来直接帖代码来分析

<Grid Name="outsideGrid" Visibility="Visible">
        <Grid Name="insideGrid" HorizontalAlignment="Left" 
              VerticalAlignment="Bottom" PreviewMouseMove="insideGrid_PreviewMouseMove">
              <!--将TextBox放入insideGrid中,我们要实现的功能也是放大这个Grid里面的所有内容-->
              <TextBox HorizontalAlignment="Left" Name="textBox1" 
                       VerticalAlignment="Top" Text="WPF制作放大镜" />
        </Grid>
        <Canvas HorizontalAlignment="Left" VerticalAlignment="Top">
            <Canvas Name="magnifierCanvas" IsHitTestVisible="False">
                <Ellipse Width="100" Height="100" Fill="LightBlue" />
                <!--为了看得清楚椭圆控件我再添加了一个一样大小的Ellipse重叠再一起,
                    将其背景颜色设置为LightBlue
                    当然你也可以不要这个Ellipse 可以删除-->
                <!--magnifierEllipse就是我们要填充的控件  就像上一个的Rectangle控件-->
                <Ellipse Width="100" Height="100" Name="magnifierEllipse">
                    <Ellipse.Fill>
                        <!--Viewbox 观景窗的范围 这里是30*30的矩形  
                            Viewbox值越大表示固定大小的Ellipse里面可以看到更多的insideGrid里面的内容
                            所以放大倍数就会越小  反之放大倍数越大。     
                            RelativeToBoundingBox相对于边境的单位。 
                            Viewport是观察孔 可以按比例来缩放视图 这里是1:1-->
                        <VisualBrush ViewboxUnits="Absolute" Viewbox="0,0,30,30"
                         ViewportUnits="RelativeToBoundingBox" Viewport="0,0,1,1"/>
                    </Ellipse.Fill>
                </Ellipse>
            </Canvas>
        </Canvas>
</Grid>


 

 

前台已经设置好了。我们似乎还没看到视图的来源, 那么如何让充当放大镜的Ellipse 随鼠标的移动而现实不同的内容呢? 接下来我们看下后台是如何处理的。我们通过一个滑鼠事件来达到目的

        VisualBrush vb;
        public MainWindow()
        {
            InitializeComponent();
            vb = (VisualBrush)magnifierEllipse.Fill; 
            vb.Visual = insideGrid;   //获取视图的来源为insideGrid中的所有内容
        }

        private void insideGrid_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            Point pos = e.MouseDevice.GetPosition(outsideGrid);  //相对于outsideGrid 获取鼠标的坐标
            Rect viewBox = vb.Viewbox;    //这里的Viewbox和前台的一样   这里就是获取前台Viewbox的值 
            double xoffset = viewBox.Width / 2.0;  //因为鼠标要让它在矩形(放大镜)的中间  那么我们就要让矩形的左上角重新移动位置
            double yoffset = viewBox.Height / 2.0; //这里先获取矩形左上角要移动的x,y坐标大小
            viewBox.X = pos.X - xoffset;           //将鼠标的坐标减去要减少的坐标来重新定位viewBox的坐标
            viewBox.Y = pos.Y - yoffset;
            //viewBox.Width = 10;           //设置viewBox的大小  等同于这里可以设置放大的倍数(原因前台代码有解释)
            //viewBox.Height = 10;
            vb.Viewbox = viewBox;          //将重新定位的viewBox值 赋值给magnifierEllipse的Viewbox 并为下一个滑鼠事件更新新值
            Canvas.SetLeft(magnifierCanvas, pos.X - magnifierEllipse.Width / 2);  //同理重新定位Canvas magnifierCanvas的坐标
            Canvas.SetTop(magnifierCanvas, pos.Y - magnifierEllipse.Height / 2);
        }


这里要注意2点:

1.前台的Canvas应该在insideGrid的下面 ,如果在其上面显示insideGrid会覆盖Canvas. 这和显示的顺序有关系。

2.滑鼠事件中获取鼠标坐标的语句是Point pos = e.MouseDevice.GetPosition(outsideGrid); 是相对于outsideGrid 。 所以Canvas应该处于outsideGrid 的子节点中而不能成为insideGrid的子节点被它包含。

总结:

通过放大镜功能就能看出。其实放大镜并不是把经过的视图真正的放大,而是通过VisualBrush 获取内容作为另一个控件的视图来源,经过设置从而达到显示放大的效果。

 

                 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值