有些沮丧,ArcGIS9.3的汉化包居然能够汉化AE!以前从来没有用过。现在实现ArcEngine的属性编辑似乎没有多少意义了!只要调用ToolBarControl添加相关的Command按钮就行了!唯一的理由就是为了界面布局的统一,哎!原来开发可以这样简单。不过理解ArcGIS和AE的设计思想确实是不应该放弃的。
接下来要学习并实现属性表的编辑,是指在属性窗体中进行批量修改!
学习内容主要是ArcDataBinding2008项目,这是AE自带的示例程序。首先这个项目包括两个类FieldPropertyDescriptor和TableWrapper;FieldPropertyDescriptor继承自PropertyDescriptor。看看PropertyDescriptor的介绍:提供类上的属性的抽象化(Provides an abstraction of a property on a class.)它的定义:public abstract class PropertyDescriptor : MemberDescriptor,可以知道PropertyDescriptor 是一个抽象类。
PropertyDescriptor 还提供以下 abstract 属性和方法:
-
包含该属性绑定到的组件的类型。
-
指示该属性是否是只读的。
-
获取属性的类型。
-
指示重置组件是否会更改该组件的值。
-
返回组件上属性的当前值。
-
重置组件属性的值。
-
将组件的值设置为一个不同的值。
-
指示是否需要持久保存该属性的值。
BindingList<T>是针对 Data Binding的数据源定义的主要接口。BindingList<T>是一个泛型类别,可以接受类别T当作自定义数据对象。
这里分析一下ArcDataBinding2008中FieldPropertyDescriptor类SetValue()方法的代码:
public override void SetValue(object component, object value) { IRow givenRow = (IRow)component; if (null != cvDomain) { // This field has a coded value domain if (!useCVDomain) { // Check value is valid member of the domain if (!((IDomain)cvDomain).MemberOf(value)) { System.Windows.Forms.MessageBox.Show(string.Format( "Value {0} is not valid for coded value domain {1}", value.ToString(), ((IDomain)cvDomain).Name)); return; } } else { // We need to convert the string value to one of the cv domain values // Loop through all the values until we, hopefully, find a match bool foundMatch = false; for (int valueCount = 0; valueCount < cvDomain.CodeCount; valueCount++) { if (value.ToString() == cvDomain.get_Name(valueCount)) { foundMatch = true; value = valueCount; break; } } // Did we find a match? if (!foundMatch) { System.Windows.Forms.MessageBox.Show(string.Format( "Value {0} is not valid for coded value domain {1}", value.ToString(), ((IDomain)cvDomain).Name)); return; } } } givenRow.set_Value(wrappedFieldIndex, value); // Start editing if we aren't already editing // 这一块很神奇,对于没有处于编辑状态的工作空间,启动为编辑工作状态StartEditing,设置weStartedEditing = true,并且停止编辑StopEditing(true)并保存。 // 如果为编辑状态,weStartedEditing = false,不执行StopEditing(true)停止编辑。 bool weStartedEditing = false; if (!wkspcEdit.IsBeingEdited()) { wkspcEdit.StartEditing(false); weStartedEditing = true; } // Store change in an edit operation wkspcEdit.StartEditOperation(); givenRow.Store(); wkspcEdit.StopEditOperation(); // Stop editing if we started here if (weStartedEditing) { wkspcEdit.StopEditing(true); } }
这里感觉到StartEditing,StartEditOperation,Store,StopEditOperation,StopEditing这样一系列方法之间的关系,如果最后没有StopEditing,数据并不会真正保存到数据源上。
参考文献:
1.BindingList
2.PropertyDescriptor实例