WinForm小白的WPF初试一:从PropertyGrid控件,输出内容到Word(上)
学WinForm也就半年,然后转到WPF,还在熟悉中。最近拿到一个任务:从PropertyGrid控件,输出内容到Word。难点有:
一.PropertyGrid控件是WinForm控件,在WPF中并不能直接从工具箱获得,或者直接在XMAL中声明使用。
如要使用,需要使用WindowFormHost控件,再在其内部装载PropertyGrid控件。当然前提要在XAML中引用CLR—NAMESAPCE的SYSTEM.WINDOWS.FORMS命名空间。详细请看此处链接:http://www.cnblogs.com/zhuqil/archive/2010/09/02/Wpf-PropertyGrid-Demo.html
二.项目中的PropertyGrid控件通过指定属性SeletedObject绑定对应的类,从而显示类中的属性,不能直接从控件中获取控件内容。
WPF作为一种声称直接操作数据的开发方式,充斥着各式绑定,用户对UI的操作实际上是对底层数据的操作。如此,我们要获取属性内容,就必须要直接从控件绑定的类中去获取。在这个项目中,PropertyGrid控件随着用户点击TreeView上不同的节点,不断切换指定其SelectedObject属性绑定节点Item(其实就是绑定节点所绑定的数据类)。
private void trvAllCheckItems_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (trvAllCheckItems.SelectedItem is ICheckItemGroup || trvAllCheckItems.SelectedItem is ICheckItem)
{
m_PropertyGrid.SelectedObject = trvAllCheckItems.SelectedItem;
}
else
{
TreeViewItem trvi = trvAllCheckItems.SelectedItem as TreeViewItem;
if (trvi != null)
{
m_PropertyGrid.SelectedObject = trvi.Tag;
}
}
}
不同级别的TreeViewItem,绑定不同的类,在底层代码中,类对我们是可知的。那么最简单的方法是直接m_PropertyGrid.SelectedObject is XX(类)判断是哪个类,然后再as转换,根据每个类的属性去获取值来输出。但这样做无疑是简单粗暴,虽然可行,但太过死板。作为初级开发人员,我还是想写一些通用性更高的方法。
假设,我不知道PropertyGrid控件绑定的对象是哪种类,其对象是动态的,未知的,那么如何获得绑定对象的属性(Property)值和属性特性(Attribute)呢?注:某些特定的特性会影响PropertyGrid控件的显示效果,如:System.ComponentModel.BrowsableAttribute。详细请看此处链接:http://blog.csdn.net/luyifeiniu/article/details/5426960
从网上搜了一种方法,使用Type.GetProperties()可以获取某一类型的属性信息集合,而遍历得到每个属性信息通过PropertyInfo.GetCustomAttributes(true)又可以获得此属性的特性。通过这种方法,我们可以得到此对象类型的每个属性名以及每个属性上的每个特性信息。那么如何获取此时对象的某个属性的值呢?
很简单,通过获取的ProperInfo.GetValue(object 此对象,null)方法,代码如下:
if (m_PropertyGrid == null || m_PropertyGrid.SelectedObject == null)
return;
object SelecteObject = m_PropertyGrid.SelectedObject;
Type t = SelecteObject.GetType();
DataSet ds = new DataSet();
string m_SaveCheckSchemaPath = ""; //有Category特性标记
bool IsHaveCategory = false;
//不创建DataTable标记,初始值为创建
bool IsNotCreateDT = false; //遍历属性,每种Category特性创建一个DataTable
foreach (PropertyInfo ProInfo in t.GetProperties())
{
System.ComponentModel.BrowsableAttribute m_BrowsableAttribute = null;
System.ComponentModel.CategoryAttribute m_CategoryAttribute = null;
System.ComponentModel.DisplayNameAttribute m_DisplayNameAttribute = null; foreach (Attribute a in ProInfo.GetCustomAttributes(true))
{ if (a is System.ComponentModel.BrowsableAttribute)
m_BrowsableAttribute = (System.ComponentModel.BrowsableAttribute)a;
if (a is System.ComponentModel.CategoryAttribute)
m_CategoryAttribute = (System.ComponentModel.CategoryAttribute)a;
if (a is System.ComponentModel.DisplayNameAttribute)
m_DisplayNameAttribute = (System.ComponentModel.DisplayNameAttribute)a;
}
if (m_BrowsableAttribute != null && m_BrowsableAttribute.Browsable == false)
continue;//属性不可见,则跳过此项
if (m_CategoryAttribute != null)
{
//有Category特性标记
IsHaveCategory = true;
foreach (DataTable dt in ds.Tables)
{
if (dt.Columns[].ColumnName == m_CategoryAttribute.Category)
{
DataRow row = dt.NewRow();
if (m_DisplayNameAttribute == null)
row[m_CategoryAttribute.Category] = ProInfo.Name;
else
row[m_CategoryAttribute.Category] = m_DisplayNameAttribute.DisplayName;
row[] = ProInfo.GetValue(SelecteObject, null);
dt.Rows.Add(row);
//已存在的类型表,则标记为不创建
IsNotCreateDT = true;
}
}
if (IsNotCreateDT)
{
IsNotCreateDT = false;
IsHaveCategory = false;
continue;//不创建新表,则跳过后续操作
} DataTable DT = new DataTable();
DT.Columns.Add(m_CategoryAttribute.Category, typeof(string));
DT.Columns.Add("", typeof(string));
DataRow Row = DT.NewRow();
if (m_DisplayNameAttribute == null)
Row[m_CategoryAttribute.Category] = ProInfo.Name;
else
Row[m_CategoryAttribute.Category] = m_DisplayNameAttribute.DisplayName;
Row[] = ProInfo.GetValue(SelecteObject, null);
DT.Rows.Add(Row);
ds.Tables.Add(DT); } //如果此属性没有CategoryAttribute,则为杂项类型
if (!IsHaveCategory)
{
foreach (DataTable dt in ds.Tables)
{
if (dt.Columns[].ColumnName == "杂项")
{
DataRow row = dt.NewRow();
if (m_DisplayNameAttribute == null)
row["杂项"] = ProInfo.Name;
else
row["杂项"] = m_DisplayNameAttribute.DisplayName;
row[] = ProInfo.GetValue(SelecteObject, null);
dt.Rows.Add(row);
//已存在的类型表,则标记为不创建
IsNotCreateDT = true;
}
}
if (IsNotCreateDT)
{
IsNotCreateDT = false;
continue;//不创建新表,则跳过后续操作
}
DataTable DT = new DataTable();
DT.Columns.Add("杂项", typeof(string));
DT.Columns.Add("", typeof(string));
DataRow Row = DT.NewRow();
if (m_DisplayNameAttribute == null)
Row["杂项"] = ProInfo.Name;
else
Row["杂项"] = m_DisplayNameAttribute.DisplayName;
Row[] = ProInfo.GetValue(SelecteObject, null);
DT.Rows.Add(Row);
ds.Tables.Add(DT);
}
IsHaveCategory = false; }
写的可能不是很简洁,嵌套很多,但已经是改良版了,天知道我之前写得有多麻烦!整个代码的目的是把未知的绑定类根据其属性分类,每个类别创建一个DataTable,存入此类的属性,最后都加到DataSet里。再之后,我们会输出这个DataSet的每张表到Word中。
WinForm小白的WPF初试一:从PropertyGrid控件,输出内容到Word(上)的更多相关文章
- WinForm窗体PropertyGrid控件的使用
使用过 Microsoft Visual Basic 或 Microsoft Visual Studio .NET的朋友,一定使用过属性浏览器来浏览.查看或编辑一个或多个对象的属性..NET 框架 P ...
- PropertyGrid控件由浅入深(一):文章大纲
Winform中PropertyGrid控件是一个非常好用的对象属性编辑工具,对于Key-Value形式的数据的处理也是非常的好用. 因为Property控件设计良好,在很小的空间内可以展示很多的内容 ...
- WPF不同线程之间的控件的访问
原文:WPF不同线程之间的控件的访问 WPF不同线程之间的控件是不同访问的,为了能够访问其他线程之间的控件,需要用Dispatcher.Invoke执行一个新的活动即可. 例如: public voi ...
- 《深入浅出WPF》学习总结之控件与布局
一.控件到底是什么 控件的本质是“数据+算法”——用户输入原始数据,算法处理原始数据并得到结果数据.问题就在于程序如何将结果数据展示给用户.同样一组数据,你可以使用LED阵列显示出来,或者是以命令行模 ...
- .NET CORE(C#) WPF 方便的实现用户控件切换(祝大家新年快乐)
微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. .NET CORE(C#) WPF 方便的实现用户控件切换(祝大家新年快乐) 快到2020年了 ...
- WPF自定义控件第一 - 进度条控件
本文主要针对WPF新手,高手可以直接忽略,更希望高手们能给出一些更好的实现思路. 前期一个小任务需要实现一个类似含步骤进度条的控件.虽然对于XAML的了解还不是足够深入,还是摸索着做了一个.这篇文章介 ...
- PropertyGrid控件由浅入深(二):基础用法
目录 PropertyGrid控件由浅入深(一):文章大纲 PropertyGrid控件由浅入深(二):基础用法 控件的外观构成 控件的外观构成如下图所示: PropertyGrid控件包含以下几个要 ...
- winform快速开发平台 -> 快速绑定ComboBox数据控件
通常我们在处理编辑窗体时.往往会遇到数据绑定.例如combobox控件绑定数据字典可能是我们经常用到的.然而在我的winform快速开发平台中我是如何处理这个频繁的操作呢? 首先,我们要绑定combo ...
- winform快速开发平台 -> 基础组件之分页控件
一个项目控件主要由及部分的常用组件,当然本次介绍的是通用分页控件. 处理思想:我们在处理分页过程中主要是针对数据库操作. 一般情况主要是传递一些开始位置,当前页数,和数据总页数以及相关关联的业务逻辑. ...
随机推荐
- django开发个人简易Blog——构建项目结构
开发之前第一步,就是构造整个的项目结构.这就好比作一幅画,第一步就是描绘轮廓,有了轮廓,剩下的就是慢慢的填充细节.项目结构规划如下图: 项目结构描述: 本项目以fengzhengBlog为根目录. a ...
- EF架构~为IEnumerable接口添加增删查等操作,原因是IEnumerable导航属性更放心
回到目录 对EF开发来说,导航属性肯定都用过,事实上,它是由VS IDE工具根据你的数据库关系结构自动生成的外键属性,在类视图中可以看到相关属性,它是以外键表名来标识的,如果是一对多的关系,那么,它会 ...
- GitHub & Bitbucket & GitLab & Coding 的对比分析
目前基于 Git 做版本控制的代码托管平台有很多种,比较流行的服务有 Github.Bitbucket. GitLab. Coding,他们各自有什么特点,个人使用者和开发团队又该如何选择? 在这篇文 ...
- iOS-数据持久化-属性列表
属性列表 属性列表文件是一种XML文件,Foundation框架中的数组和字典等都可以于属性列表文件相互转换. NSArray类常用读写属性列表文件的方法: +arrayWithContentsOfF ...
- SVN命令模式批量更新多个项目
使用svn作为版本管理是,在一个仓库下边同时建立多个项目,每天上班都需要一个个更新,为了发挥程序员懒的精神,能让电脑做的,绝不手工操作.作为自动化处理,在windows环境,首先想到了bat Tort ...
- js防止客户端多触发
代码: /***防止多触发**id 必须唯一*fn 回掉函数*wait 延迟多长时间**使用例子:* ToPreventMoreTrigger('id', function () {//注意 id 是 ...
- String详解
在开发中,我们都会频繁的使用String类,掌握String的实现和常用方法是必不可少的,当然,我们还需要了解它的内部实现. 一. String的实现 在Java中,采用了一个char数组实现Stri ...
- Reporting Service 配置SMTP和设置订阅出现的异常
SSRS能够按照schedule,以mail的形式发送report,这是通过设置subscription report来实现的. 1,发送mail需要在SSRS中配置SMTP Server,如果没有R ...
- 详解JavaScript模块化开发
什么是模块化开发? 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了,jQuery,Ajax,Node.Js,MVC,MVVM等 ...
- 如何用sublime 编写sass
使用了Sublime Text也有一段时日了,然后在现在而言,小觉的coding工具已经非其莫属了,接着小觉因为近期忙着项目的原因,同时还要抽空编辑博客的原因,就暂时把它放在一旁了,现在偶然想起也就说 ...