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快速开发平台 -> 基础组件之分页控件
一个项目控件主要由及部分的常用组件,当然本次介绍的是通用分页控件. 处理思想:我们在处理分页过程中主要是针对数据库操作. 一般情况主要是传递一些开始位置,当前页数,和数据总页数以及相关关联的业务逻辑. ...
随机推荐
- SOA服务设计与实现的几个语言无关的原则速记
一.SOA定义 SOA即面向服务架构(Service-Oriented Architecture).在SOA中,一切皆服务.一个服务是通过消息交换来调用的程序,一个信息系统是共同完成一个特定任务的一组 ...
- Atitit 桌面软件跨平台gui解决方案 javafx webview
Atitit 桌面软件跨平台gui解决方案 javafx webview 1.1. 双向js交互1 1.2. 新弹出窗口解决1 1.3. 3.文档对象入口dom解析1 1.4. 所以果断JavaFX, ...
- salesforce 零基础学习(二十六)自定义图表chart简单介绍(使用apex和VF实现)
chart在报表中经常使用到,他可以使报表结果更加直观的展现给用户.salesforce支持VF和apex代码来更好的展示chart. chart分类:常用的图表样式有饼状图,柱状图,折线图,条形图, ...
- SQLServer数据库还原提示 数据库正在使用,无法获得独占访问权
还原数据库的时候提示下图的错误:
- jquery 之 Deferred 使用与实现
观察者模式是开发中经常使用的模式,这个模式由两个主要部分组成:主题和观察者.通过观察者模式,实现主题和观察者的解耦. 主题负责发布内容,而观察者则接收主题发布的内容.通常情况下,观察者都是多个,所以, ...
- js对象、数组转换字符串
对象转换成字符串需要使用toString()方法. 1 var a = function(){ 2 console.log(111); 3 }; 4 var b = a.toString(); 5 c ...
- Android入门(六)碎片
原文链接:http://www.orlion.ga/493/ 一.碎片 碎片(Fragment)是一种可以嵌入在活动当中的 UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常 ...
- spring 源码分析之BeanPostProcessor
1.官方解答: Factory hook that allows for custom modification of new bean instances, e.g. checking for ma ...
- 一种利用 Cumulative Penalty 训练 L1 正则 Log-linear 模型的随机梯度下降法
Log-Linear 模型(也叫做最大熵模型)是 NLP 领域中使用最为广泛的模型之一,其训练常采用最大似然准则,且为防止过拟合,往往在目标函数中加入(可以产生稀疏性的) L1 正则.但对于这种带 L ...
- Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十三】
<Web 前端开发精华文章推荐>2014年第2期(总第23期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...