用MVVM模式开发中遇到的零散问题总结(5)——将动态加载的可视元素保存为图片的控件,Binding刷新的时机
原文:用MVVM模式开发中遇到的零散问题总结(5)——将动态加载的可视元素保存为图片的控件,Binding刷新的时机
在项目开发中经常会遇到这样一种情况,就是需要将用户填写的信息排版到一张表单中,供打印或存档。这里就以保存为图片为例,比如我需要实现下面的功能:
将图片
根据用户信息保存为
总体思路
1.建个UserControl将背景设置为表单图片。
2.在姓名的位置添加Textblock控件,将Text绑定到Name属性上。
3.动态加载UserControl,再将整个UserControl可视树转化为一张图片,保存。
实现过程
关于怎么设置背景,和布局Textblock我就不多说了,相信大家都会。要注意的是,因为之后我要用XamlReader.Load()来动态加载XAML所以UserControl要把X:Class="xxx"这段给删了。
接下来直接看代码,基本每句都写了注释
需要生成图片的XAML:
<Grid >
<Image Source="pack://siteoforigin:,,,/view/Print/Images/XXX.jpg" />
<TextBlock Height="88" HorizontalAlignment="Left" Margin="928,1624,0,0" Text="{Binding Name}" VerticalAlignment="Top" Width="240" FontSize="64" />
</Grid>
控件代码:
/// <summary>
/// 设置需要生成的Xaml的地址
/// </summary>
public string XamlUrl
{
get { return (string)GetValue(XamlUrlProperty); }
set { SetValue(XamlUrlProperty, value); }
}
public static readonly DependencyProperty XamlUrlProperty =
DependencyProperty.Register("XamlUrl", typeof(string), typeof(CopXaml2Bmp), null); /// <summary>
/// 生成的图片地址
/// </summary>
public string BmpUrl
{
get { return (string)GetValue(BmpUrlProperty); }
set { SetValue(BmpUrlProperty, value); }
}
public static readonly DependencyProperty BmpUrlProperty =
DependencyProperty.Register("BmpUrl", typeof(string), typeof(CopXaml2Bmp),null); /// <summary>
/// 设置dpi
/// </summary>
public int Dpi
{
get { return (int)GetValue(DpiProperty); }
set { SetValue(DpiProperty, value); }
}
public static readonly DependencyProperty DpiProperty =
DependencyProperty.Register("Dpi", typeof(int), typeof(CopXaml2Bmp), null); private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
try
{
FileStream fs = new FileStream(XamlUrl, FileMode.Open, FileAccess.Read);//动态加载XAML
ContentControl myGrid = XamlReader.Load(fs) as ContentControl;
//myGrid.DataContext = this.DataContext;//设置datacontext
double width = (this.Parent as Grid).Width;//获取母容器的高宽
double height = (this.Parent as Grid).Height; myGrid.Loaded += new RoutedEventHandler((sender1, e1) =>
{
(this.Parent as Grid).Children.Remove(myGrid);//从母容器中移除该内容 var size = new Size(myGrid.Width, myGrid.Height);
myGrid.Measure(size);//二次布局,因为只是在内存中没有显示在UI上,需要经过布局才有内容
myGrid.Arrange(new Rect(new Point(, ), size)); System.IO.FileStream fs1 = new System.IO.FileStream(BmpUrl, System.IO.FileMode.Create);//创建一个文件流来存图片
RenderTargetBitmap bmp = new RenderTargetBitmap((int)myGrid.Width, (int)myGrid.Height, Dpi, Dpi, PixelFormats.Default);//visual对象转位图
bmp.Render(myGrid);//呈现visual
BitmapEncoder encoder = new TiffBitmapEncoder();//编码为图像流
encoder.Frames.Add(BitmapFrame.Create(bmp));//添加帧
encoder.Save(fs1);//保存文件
fs1.Close(); (this.Parent as Grid).Width = width;//大小还原
(this.Parent as Grid).Height = height;
});
(this.Parent as Grid).Width = myGrid.Width;//将母容器的高宽设置为需要的大小
(this.Parent as Grid).Height = myGrid.Height;
(this.Parent as Grid).Children.Add(myGrid);//添加进母容器让其暂时显示,以显示绑定的信息 }
catch
{ }
}
使用控件代码(其父容器的datacontext中含有Name属性):
<Assistant:Xaml2Bmp XamlUrl="view/Print/XXX.xaml" BmpUrl="d:/test.bmp" Dpi="96" HorizontalAlignment="Right" Height="100" Margin="0,0,204,44" VerticalAlignment="Bottom" Width="100"/>
这样就将动态加载的XAML生成了d:/test.bmp图片。
说实话,实现这个功能没什么难的,写这篇博客的目的在于,做这个控件时让我了解到了一个Binding刷新的问题。
通过XamlReader.Load()加载的XAML对其设置datacontext,对应的Textblock.Text的内容为"",而不是绑定的内容。而当元素在UI上显示时,才会刷新数据绑定,从而让Textblock.Text的内容为绑定到的datacontext对应的节点上。
所以上面的代码中,我把动态加载的XAML添加进了控件的父容器中,让其刷新绑定,并在其加载完成后从父容器中移除该控件,对于用户来说是什么都看不到的,然后将其转换为图片。父容器的大小也要能够容纳整个控件才行,生成的图片显示的只有父容器的范围部分。
更新:实践证明如果需要生成的元素里面包含自定义style的时候,需要在元素还在界面上显示时进行打印,一旦从UI上Remove了该元素后貌似就会把自定义style释放掉,生成的图片有关自定义控件的地方就为空白,也就是说WPF程序当元素在UI上显示时才会加载样式,一旦从UI上移除就卸载掉,以提高性能。所以上面的代码需要把(this.Parent as Grid).Children.Remove(myGrid);这句移到生成图片那一句的后面。
用MVVM模式开发中遇到的零散问题总结(5)——将动态加载的可视元素保存为图片的控件,Binding刷新的时机的更多相关文章
- 用MVVM模式开发中遇到的零散问题总结(4)——自制摄像头拍摄大头贴控件
原文:用MVVM模式开发中遇到的零散问题总结(4)--自制摄像头拍摄大头贴控件 一直有个疑问,为什么silverlight对摄像头支持这么好,WPF却一个库都没有....于是我各种苦恼啊,各种Code ...
- 用MVVM模式开发中遇到的零散问题总结(2)
原文:用MVVM模式开发中遇到的零散问题总结(2) 本节目录: 1.解决动画属性被劫持问题 2.设置页面焦点默认所在对象 3.XAML模拟键盘按键 4.DataGrid数据源绑定到复杂格式(dynam ...
- 用MVVM模式开发中遇到的零散问题总结(3)——自制正则表达式万能绑定转换器
原文:用MVVM模式开发中遇到的零散问题总结(3)--自制正则表达式万能绑定转换器 前言 最近接受了3个项目的洗礼,出差近3个月,各种北京.广州.昆明来回奔波,好久没写博客了,之前我觉得我遇到的问题都 ...
- 用MVVM模式开发中遇到的零散问题总结(1)
https://www.cnblogs.com/tong-tong/archive/2011/11/28/2250948.html
- 会员管理系统的设计和开发(2)-- RDLC报表的设计及动态加载
在上篇<会员管理系统的设计和开发(1)>介绍了关于会员系统的一些总体设计思路和要点,经过一段时间开发,软件终于完成并发布.在这期间,碰到了不少技术难点,并积累了不少开发心得和经验,本篇继续 ...
- 【WPF开发备忘】使用MVVM模式开发中列表控件内的按钮事件无法触发解决方法
实际使用MVVM进行WPF开发的时候,可能会用到列表控件中每行一个编辑或删除按钮,这时直接去绑定,发现无法响应: <DataGridTemplateColumn Header="操作& ...
- Winform开发框架之客户关系管理系统(CRM)的开发总结系列4-Tab控件页面的动态加载
在前面介绍的几篇关于CRM系统的开发随笔中,里面都整合了多个页面的功能,包括多文档界面,以及客户相关信息的页面展示,这个模块就是利用DevExpress控件的XtraTabPage控件的动态加载实现的 ...
- C#中动态加载和卸载DLL
在C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方卸载.在C#中我们也能使用Assembly.LoadFile实 ...
- C#.Net 如何动态加载与卸载程序集(.dll或者.exe)1----C#中动态加载和卸载DLL
我们知道在C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方卸载. 在C#中我们也能使用Assembly.Load ...
随机推荐
- [Docker] Prune Old Unused Docker Containers and Images
In this lesson, we will look at docker container prune to remove old docker containers. We can also ...
- Mac OSX 下配置 LNMP开发环境
不久前负责了一个项目需要配置PHP7的开发环境,因为之前所有的项目用的是PHP5的,所以研究了这些东西,但是很遗憾,电脑出了问题,不得已重装了系统,然后你懂得...什么都没有了,要重新来过.. 虽然本 ...
- Springmvc+Shiro实战
原文链接:http://blog.csdn.net/qq_37936542/article/details/79010449 springmvc+shiro实现系统粗细粒度的权限管理步骤: 1:表格设 ...
- Surf算法特征点检测与匹配
Speeded Up Robust Features(SURF,加速稳健特征),是一种稳健的局部特征点检测和描述算法.最初由Herbert Bay发表在2006年的欧洲计算机视觉国际会议(Europe ...
- 忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(3)输入输出函数
一.基本的输入和输出函数的用法 1.printf() //屏幕输出 用法: (1)printf("字符串\n"); (2)printf("输出控制符", 输出 ...
- Oracle成长点点滴滴(2)— 权限管理
权限管理中权限包含系统权限以及对象权限.在解说权限管理之前我们先来了解用户的创建以及授权这些前提. 1. 创建用户以及授权 Ø 默认用户 既然提到了创建用户,首先必须先把用户的知识攻克了. ...
- 【BZOJ 1005】[HNOI2008]明明的烦恼(化简的另一种方法)
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1005 [题意] [题解] 题目和题解在上一篇; 这里 对 [(m^(n-2-tot)) ...
- 【Dijkstra+邻接表求次短路】POJ Sightseeing 3463
Language: Default Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7766 Ac ...
- 欢迎阅读 Erlang OTP 设计原理文档
http://erldoc.com/doc/otp-design-principles/index.html 原文: OTP Design Principles 翻译: ShiningRay 有任何问 ...
- boost::any在降低模块之间耦合性的应用
作者:朱金灿 来源:http://blog.csdn.net/clever101 在开发大型系统中,遵循这样一个原则:模块之间低耦合,模块内高内聚.比如系统中模块有界面模块和算法模块两种,一般是界面模 ...