原文:抛砖引玉 【镜像控件】 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. 怎样cp文件夹时忽略指定的文件夹和文件

    在备份ltedecoder程序时,须要把此文件夹拷由到bak文件夹下.但decoder文件夹下有个大文件,不须要备份,还有日志问题,也不须要备份,怎样实现呢?? 方法: cd /source-dir ...

  2. $_SERVER['DOCUMENT_ROOT']

    $_SERVER['DOCUMENT_ROOT'] 一.总结 $_SERVER 是一个包含了诸如头信息(header).路径(path).以及脚本位置(script locations)等等信息的数组 ...

  3. Docker搭建ES

    Centos7安装ES 和 Docker搭建ES 文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws 一.linux centos7.x安装ES ...

  4. Linux下多线程查看工具(pstree、ps、pstack),linux命令之-pstree使用说明, linux 查看线程状态。 不指定

    0.最常用 pstree:[root@iZ25dcp92ckZ temp]# pstree -a|grep multe  |       |   `-multepoolser  |       |   ...

  5. js获取浏览器和元素对象的尺寸

    1.屏幕尺寸 window.screen.height //屏幕分辨率的高 window.screen.width //屏幕分辨率的宽 window.screen.availHeight //屏幕可用 ...

  6. angular风格指南

    原文 https://www.jianshu.com/p/1a0a0a74769a 大纲 综述 1.单一职责 2.命名 3.LIFT-D应用程序结构 4.组件 综述 以下说的准则是根据angular官 ...

  7. text输入框改变事件

    前端页面开发的很多情况下都需要实时监听文本框输入,比如腾讯微博编写140字的微博时输入框hu9i动态显示还可以输入的字数.过去一般都使用onchange/onkeyup/onkeypress/onke ...

  8. thinkphp中ajax使用实例(thinkphp内置支持ajax)

    thinkphp中ajax使用实例(thinkphp内置支持ajax) 一.总结 1.thinkphp应该是内置支持ajax的,所以请求类型里面才会有是否是ajax // 是否为 Ajax 请求 if ...

  9. MySQL建立双向主备复制server配置方法

    1.环境描写叙述 serverA(主) 192.85.1.175 serverB(从) 192.85.1.176 Mysql版本号:5.1.61 系统版本号:System OS:ubuntu 10.1 ...

  10. android webview中的音乐的暂停与播放

    前段时间有这样一个需求,webview显示一个带音乐的网页,在播放音乐的时候进入第三方软件暂停播放,返回时继续播放.后来参考了两篇文章解决了这个问题. AudioManager audioManage ...