原文:抛砖引玉 【镜像控件】 WPF实现毛玻璃控件不要太简单

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Vblegend_2013/article/details/83447420

源码已封装成 MirrorGrid类 可以直接在XAML里添加

根据需要可以把Grid 改为  button border等控件

注意 Target必须为当前控件下层的控件对象

 

加个BlurEffect就是毛玻璃效果

<!--玻璃层控件-->
<local:MirrorGrid
Background="Red"
Target="{Binding ElementName=box}"
Width="150"
Height="100"
x:Name="thumb" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" MouseDown="thumb_MouseDown" MouseMove="thumb_MouseMove" MouseUp="thumb_MouseUp">
<local:MirrorGrid.Effect>
<BlurEffect Radius="20" RenderingBias="Performance"/>
</local:MirrorGrid.Effect>
</local:MirrorGrid>

 

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media; namespace WpfApp2
{
/// <summary>
/// 镜像格子
/// </summary>
public class MirrorGrid : Grid
{ /// <summary>
/// 目标对象
/// </summary>
public FrameworkElement Target
{
get { return (FrameworkElement)GetValue(TargetProperty); }
set { SetValue(TargetProperty, value); }
} /// <summary>
/// 目标对象属性
/// </summary>
public static readonly DependencyProperty TargetProperty =
DependencyProperty.Register("Target", typeof(FrameworkElement), typeof(MirrorGrid),
new FrameworkPropertyMetadata(null)); /// <summary>
/// 重写基类 Margin
/// </summary>
public new Thickness Margin
{
get { return (Thickness)GetValue(MarginProperty); }
set { SetValue(MarginProperty, value); }
}
public new static readonly DependencyProperty MarginProperty = DependencyProperty.Register("Margin", typeof(Thickness), typeof(MirrorGrid), new FrameworkPropertyMetadata(new Thickness(0), new PropertyChangedCallback(OnMarginChanged)));
private static void OnMarginChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
((FrameworkElement)target).Margin = (Thickness)e.NewValue;
//强制渲染
((FrameworkElement)target).InvalidateVisual();
} protected override void OnRender(DrawingContext dc)
{
var Rect = new Rect(0, 0, RenderSize.Width, RenderSize.Height);
if (Target == null)
{
dc.DrawRectangle(this.Background, null, Rect);
}
else
{
this.DrawImage(dc, Rect);
} } private void DrawImage(DrawingContext dc, Rect rect)
{
VisualBrush brush = new VisualBrush(Target)
{
Stretch = Stretch.Fill,
};
var tl = this.GetElementLocation(Target);
var sl = this.GetElementLocation(this);
var lx = (sl.X - tl.X) / Target.ActualWidth;
var ly = (sl.Y - tl.Y) / Target.ActualHeight;
var pw = this.ActualWidth / Target.ActualWidth;
var ph = this.ActualHeight / Target.ActualHeight;
brush.Viewbox = new Rect(lx, ly, pw, ph);
dc.DrawRectangle(brush, null, rect);
} /// <summary>
/// 获取控件元素在窗口的实际位置
/// </summary>
/// <param name="Control"></param>
/// <returns></returns>
public Point GetElementLocation(FrameworkElement Control)
{
Point location = new Point(0, 0);
FrameworkElement element = Control;
while (element != null)
{
var Offset = VisualTreeHelper.GetOffset(element);
location = location + Offset;
element = (FrameworkElement)VisualTreeHelper.GetParent(element);
}
return location;
} }
}

 

测试源码

<Window x:Class="WpfApp2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<Grid ClipToBounds="True">
<!--下层被模糊层-->
<Grid x:Name="box"
Background="AntiqueWhite"
HorizontalAlignment="Left" Height="332" VerticalAlignment="Top" Width="551">
<Grid HorizontalAlignment="Left" Height="260" Margin="0,0,0,0" VerticalAlignment="Top" Width="345">
<Grid.Background>
<ImageBrush ImageSource="123.png"/>
</Grid.Background>
</Grid>
<Ellipse Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="114" Margin="345,218,0,0" Stroke="Black" VerticalAlignment="Top" Width="206"/>
</Grid>
<!--玻璃层控件-->
<local:MirrorGrid
Background="Red"
Target="{Binding ElementName=box}"
Width="150"
Height="100"
x:Name="thumb" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" MouseDown="thumb_MouseDown" MouseMove="thumb_MouseMove" MouseUp="thumb_MouseUp">
<local:MirrorGrid.Effect>
<BlurEffect Radius="20" RenderingBias="Performance"/>
</local:MirrorGrid.Effect>
</local:MirrorGrid>
<!--测试边框线-->
<Rectangle Stroke="#FF2DEC0E"
IsHitTestVisible="False"
Width="{Binding ElementName=thumb, Path=Width}"
Height="{Binding ElementName=thumb, Path=Height}"
Margin="{Binding ElementName=thumb, Path=Margin}"
HorizontalAlignment="Left" VerticalAlignment="Top"/> </Grid>
</Window>

 

后台

using System.Windows;
using System.Windows.Input; namespace WpfApp2
{
/// <summary>
/// Window1.xaml 的交互逻辑
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
} private bool isDragging;
private Point clickPosition; private void thumb_MouseDown(object sender, MouseButtonEventArgs e)
{
isDragging = true;
var draggableElement = sender as UIElement;
clickPosition = e.GetPosition(this);
draggableElement.CaptureMouse();
} private void thumb_MouseUp(object sender, MouseButtonEventArgs e)
{
isDragging = false;
var draggableElement = sender as UIElement;
draggableElement.ReleaseMouseCapture();
} private void thumb_MouseMove(object sender, MouseEventArgs e)
{
var draggableElement = sender as UIElement;
if (isDragging && draggableElement != null)
{
Point currentPosition = e.GetPosition(this.Parent as UIElement);
Thickness s = new Thickness(thumb.Margin.Left + currentPosition.X - clickPosition.X, thumb.Margin.Top + currentPosition.Y - clickPosition.Y,0,0);
thumb.Margin = s;
clickPosition = currentPosition;
}
} }
}

 

 

抛砖引玉 【镜像控件】 WPF实现毛玻璃控件不要太简单的更多相关文章

  1. 实现控件WPF(4)----Grid控件实现六方格

    PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘.目前又不当COO,还是得用心记代码哦! 利用Grid控件能很轻松帮助我们实现各种布局.上面就是一个通过Grid单元格 ...

  2. WPF中Ribbon控件的使用

    这篇博客将分享如何在WPF程序中使用Ribbon控件.Ribbon可以很大的提高软件的便捷性. 上面截图使Outlook 2010的界面,在Home标签页中,将所属的Menu都平铺的布局,非常容易的可 ...

  3. WPF 调用WinForm控件

    WPF可以使用WindowsFormsHost控件做为容器去显示WinForm控件,类似的用法网上到处都是,就是拖一个WindowsFormsHost控件winHost1到WPF页面上,让后设置win ...

  4. InteropBitmap指定内存,绑定WPF的Imag控件时刷新问题。

    1.InteropBitmap指定内存,绑定WPF的Imag控件的Source属性 创建InteropBitmap的时候,像素的格式必须为PixelFormats.Bgr32, 如果不是的话在绑定到I ...

  5. 在WPF程序中将控件所呈现的内容保存成图像(转载)

    在WPF程序中将控件所呈现的内容保存成图像 转自:http://www.cnblogs.com/TianFang/archive/2012/10/07/2714140.html 有的时候,我们需要将控 ...

  6. WPF 分页控件 WPF 多线程 BackgroundWorker

    WPF 分页控件 WPF 多线程 BackgroundWorker 大家好,好久没有发表一篇像样的博客了,最近的开发实在头疼,很多东西无从下口,需求没完没了,更要命的是公司的开发从来不走正规流程啊, ...

  7. 【WPF】监听WPF的WebBrowser控件弹出新窗口的事件

    原文:[WPF]监听WPF的WebBrowser控件弹出新窗口的事件 WPF中自带一个WebBrowser控件,当我们使用它打开一个网页,例如百度,然后点击它其中的链接时,如果这个链接是会弹出一个新窗 ...

  8. 在WPF的WebBrowser控件中抑制脚本错误

    原文:在WPF的WebBrowser控件中抑制脚本错误 今天用WPF的WebBrowser控件的时候,发现其竟然没有ScriptErrorsSuppressed属性,导致其到处乱弹脚本错误的对话框,在 ...

  9. 浅尝辄止WPF自定义用户控件(实现颜色调制器)

    主要利用用户控件实现一个自定义的颜色调制控件,实现一个小小的功能,具体实现界面如下. 首先自己新建一个wpf的用户控件类,我就放在我的wpf项目的一个文件夹下面,因为是一个很小的东西,所以就没有用mv ...

随机推荐

  1. 实现indexOf

    1.先判断Array数组是否含有indexOf方法,如果有直接返回结果:如果没有则利用循环比较得到结果. function indexOf(arr, item) { if(Array.prototyp ...

  2. lua不同模块调用

    一.起因 由于准备把lua加入的系统中,还需把字符串解析json.下了个json的lua,目前还没有搞定.但是一个lua,调用其他lua文件模块,目前刚刚搞定. 暂作记录. 二. 模块调用测试 1. ...

  3. windows+python3+opencv3.4安装

    1.安装anaconda. 2.pip install opencv-python 网上很多关于python opencv安装说明,步骤极其繁琐,其实按照本说明只需两步就可安装完成.

  4. Topological Spaces(拓扑空间)

    拓扑空间的定义有多种形式,通过 open sets(开集)的形式定义是最为常见的拓扑空间定义形式. 1. 通过开集(open sets)定义 拓扑空间由一个有序对 (X,τ) 表示,X 表示非空集合, ...

  5. 2014年武汉的IT行情好像不太好

    本周,加入武汉一起好工作一周了,也就是说本次找工作彻底结束了. 总的来说,求职行情不太行,双方都匹配的工作好少呀. 1. 武汉财富基石,过了一面,第二面没有去.   钱太少,4K多,跳楼价. 2.武汉 ...

  6. UVA 10106 Product (大数相乘)

    Product The Problem The problem is to multiply two integers X, Y. (0<=X,Y<10250) The Input The ...

  7. mysql mha高可用架构的安装

    MMM无法全然地保证数据的一致性,所以MMM适用于对数据的一致性要求不是非常高.可是又想最大程度的保证业务可用性的场景对于那些对数据一致性要求非常高的业务,非常不建议採用MMM的这样的高可用性架构.那 ...

  8. ChangeWindowMessageFilterEx 概述(用于取消低权限程序向高权限程序发送消息不成功的限制,分6个等级)

    ChangeWindowMessageFilterEx 函数,为指定窗口修改用户界面特权隔离 (UIPI) 消息过滤器. 函数原型: BOOL WINAPI ChangeWindowMessageFi ...

  9. C语言数据类型取值范围解析

    版权声明:本文为博主原创文章,未经博主允许不得转载.   为什么int类型的取值范围会是-2^31 ~ 2^31-1  ,为什么要减一呢? 计算机里规定,8位二进制为一个字节,拿byte来说,一个BY ...

  10. JavaScript 正則表達式

    一.简单介绍 1.什么是正則表達式 正則表達式本身就是一种语言,这在其他语言是通用的. 正則表達式(regular expression)描写叙述了一种字符串匹配的模式,能够用来检查一个串是否含有某种 ...