ComponentOne FlexGrid for WinForms 中文版快速入门(5)--设置单元格类型(下)

上一章中我们介绍了一些基本的单元格类型的设置,在这一章节我们将分享如何设置掩码、验证和自定义单元格类型。以及在编辑单元格期间触发的事件。
如果您是第一次阅读本系列文章,建议您阅读:
1.1.1 掩

C1FlexGrid控件还支持屏蔽编辑。当用户输入时,这种类型的编辑可以使用一种输入掩码来提供一个模板,并自动验证该输入。该掩码由“编辑掩码”属性明确指定,它可以通过普通的文本字段和下拉组合区域来使用。

掩码字符串包括两种类型的字符:文字字符,这可以成为输入的一部分;模板字符,这是属于特定类别的占位字符(例如,数字或字母)。例如,下面的代码将一个编辑掩码“(999)999-9999”指定到第一列,该掩码包含的是电话号码,(数字“9”是一个可以代表任何数字的占位字符):

· Visual Basic

'建立一个电话号码的编辑掩码。

_flex.Cols(1).EditMask = "(999) 999-9999"

· C#

//建立一个电话号码的编辑掩码。

_flex.Cols[1].EditMask = "(999) 999-9999";

当你将“编辑掩码”属性设置为一个非空的字符串,会导致它必须使用内置的屏蔽编辑,即便该列包含日期/时间值(通常,一个“日期时间提取器”控件可以用于编辑这些列)。如果你有只含时间(没有日期)的“日期时间”列,这使用起来将格外方便。在这些情况下,你可以设置以下属性来使用一个屏蔽编辑器,而不是一个“日期时间提取器”控件:

· Visual Basic

flex.Cols(1).DataType = GetType(DateTime)

_flex.Cols(1).Format = "hh:mm tt"

_flex.Cols(1).EditMask = "99:99 LL"

· C#

flex.Cols[1].DataType = typeof(DateTime);

_flex.Cols[1].Format = "hh:mm tt";

_flex.Cols[1].EditMask = "99:99 LL";

你也可以在设计时通过使用“输入掩码”对话框来设置“编辑掩码”属性。

要访问输入掩码对话框可通过以下两种途经,“列任务”菜单或C1FlexGrid列编辑器

· 进入“列任务”菜单,在编辑掩码框中单击省略号按钮。

· 进入C1FlexGrid列编辑器,找到左窗格中的编辑掩码属性,并单击它旁边的省略号按钮。

注意:输入掩码对话框是特定的列,并且只会更改所选定的列的编辑掩码属性。

有关建立掩码字符串的语法的详细信息,请参阅该控件参考资料部分的编辑掩码属性。

如果在同一列的不同单元格需要不同的掩码,需要捕获编辑前事件,并为当前单元格将编辑掩码属性设置一个的适当的值。

1.1.2 验证

在许多情况下,为确保用户的数据输入是有效的,只有编辑掩码是不够的。例如,掩码不会让你指定一个可能值的范围,或以另一个单元格的内容为基础来验证当前单元格。

在这些情况下,需要捕获验证编辑事件,看看在“编辑器-文本”属性中包含的值是不是当前单元格的有效条目(在这一点上,单元格仍然有它的原始值)。如果该输入的是无效的,将“取消”参数设置为“”,表格将保持编辑模式直到用户输入一个有效的条目。

例如,将下面的代码验证输入到一个货币列,以确保输入的值处于1000和10000之间:

· Visual Basic

Private Sub _flex_ValidateEdit(ByVal sender As Object, ByVal e As

C1.Win.C1FlexGrid.ValidateEditEventArgs) Handles _flex.ValidateEdit

'验证金额。

If _flex.Cols(e.Col).DataType Is GetType(Decimal) Then

Try

Dim dec As Decimal = Decimal.Parse(_flex.Editor.Text())

If (dec < 1000) Or (dec > 10000) Then

MessageBox.Show("Value must be between 1,000 and 10,000")

e.Cancel = True

End If

Catch

MessageBox.Show("Value not recognized as a Currency")

e.Cancel = True

End Try

End If

End Sub

· C#

private void _flex_ValidateEdit( object sender, ValidateEditEventArgs e)

{

//验证金额。

if (_flex.Cols[e.Col].DataType == typeof(Decimal))

{

try

{

Decimal dec = Decimal.Parse(_flex.Editor.Text);

if ( dec < 1000 || dec > 10000 ) {

MessageBox.Show("Value must be between 1,000 and 10,000");

e.Cancel = true;

}

}

catch

{

MessageBox.Show("Value not recognized as a Currency");

e.Cancel = true;

}

}

}

1.1.3 自定义编辑器

内置的编辑器可以具备很大的灵活性和能力,但在某些情况下,你可能要使用外部控件作为专门的编辑器。例如,你可能想使用提供了一个下拉计算器的C1NumericInput控件来输入数字,或使用一个编辑器来从多列的列表中进行选择,或你可以用自己写的一个专门的控件来编辑你的业务对象。

从基本的“控件”类型派生出的任何控件都可以作为一个基本的表格编辑器使用。实现了IC1EmbeddedEditor接口(在C1.Common.dll的定义)的控件可以用表格提供更好的整合和更先进的功能。有关IC1EmbeddedEditor接口的更多详细信息,请参阅“编辑属性”。

要将一个控件作为自定义编辑器来使用,所有你必须要做的就是使用其“编辑”属性将控件的一个实例与一个表格列或一个样式关联到一起。你可以在设计器(使用列编辑器)或在代码中实现这步操作。在此之后,表格将自动使用该控件。

要在设计时定义自定义编辑器,先要将编辑器控件的一个实例添加到窗体,然后从C1FlexGrid任务菜单上选择设计器来打开C1FlexGrid列编辑器。选择应使用自定义编辑器的列,并将其编辑器的属性设置为新的编辑器控件的名称。

例如,要将NumericUpDown控件作为一个表格编辑器使用,请按照下列步骤操作:

1. 添加一个C1FlexGrid控件到窗体。

2. 将NumericUpDown控件添加到窗体,并将其“边框样式”属性设置为“”。

3. 从C1FlexGrid任务菜单上选择设计器。有关访问C1FlexGrid列编辑器的更多详细信息,请参阅“访问C1FlexGrid的列编辑器”(第143页)。

4. 在C1FlexGrid列编辑器上,选择第一个滚动的表格列,并将它的“编辑器”属性设置到NumericUpDown1

运行该项目并编辑第一列中的一些值。请注意表格如何定位和初始化NumericUpDown控件,以便你可以编辑单元格的值。当你完成对一个单元格的编辑,单击不同的单元格或按TAB键来移动到下一个。请注意新的值是如何应用到单元格的。

你也可以使用代码来给表格指定自定义编辑器:

· Visual Basic

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles MyBase.Load

'创建自定义编辑器。

Dim editor as New NumericUpDown()

editor.BorderStyle = BorderStyle.None

' 将自定义编辑器分配到表格。

_flex.Cols(1).Editor = editor

End Sub

· C#

private void Form1_Load(object sender, System.EventArgs e)

{

//创建自定义编辑器。

NumericUpDown editor = new NumericUpDown();

editor.BorderStyle = BorderStyle.None;

// 将自定义编辑器分配到表格。

_flex.Cols[1].Editor = editor;

}

创建自定义编辑器

从Control基类派生出的任何控件都可以用来作为一个表格编辑器使用。这是完全有可能的,因为在访问诸如“文本”和“界限”之类的属性,或诸如“请假”和“文本变更”之类的事件时,表格对基类控件有足够的了解。在很多情况下,这种程度的支持就足够了。

然而,在某些情况下,你可能想使用一些不那么密切地遵守基类的控件。例如,“日期时间提取器”控件有一个“”属性,它应该用来检索编辑过的值,而不是文本的值。在这些情况下,你可以在IC1EmbeddedEditor接口上实现一个或多个方法来覆盖默认的行为。例如,在C1Input库中所有控件都支持IC1EmbeddedEditor,因此,它与C1FlexGrid(还有C1TrueDBGrid)整合密切。

IC1EmbeddedEditor接口相当简单,并且由于表格是使用后期绑定与之相结合的,你甚至不需要实现其所有成员。只需要落实那个对你的编辑器控件有意义的即可。

接口确实提供了足够的灵活性来使几乎所有的控件都能作为一个表格编辑器使用。你甚至可以使用UITypeEditor这些类型来作为表格编辑器。要做到这一点,你需要一个包装类:

1. 派生于Control(UITypeEditor不可以)。

2. 实现IC1EmbeddedEditor接口。

3. 封装相应的UITypeEditor。

我们在CustomEditors样品中为这个包装类提供的源代码。

使用UITypeEditor包装类,你可以与C1FlexGrid一起使用任何UITypeEditors。.NET可以为编辑颜色,字体,文件名等提供几个UITypeEditors。你也可以自己写UITypeEditors,在某些情况下,这比写控件容易。

可用的示例项目

例如与C1FlexGrid一起使用内置的、自定义的和UITypeEditor编辑器,请在ComponentOne 帮助中心上参阅“自定义编辑器”样本。

1.1.4 编辑模式

你可以通过阅读编辑属性值来确定表格是否处于编辑模式。如果这个属性恢复为“无效”,则表格不是在编辑模式。不然,属性恢复一个引用值到正在用于编辑该单元格的控件(该控件可能是一个“文本框”,一个“组合框”,或其他类型的控件),表格就是处于编辑模式。你可以“开始编辑”的方法将表格程式化地设定在编辑模式下,并使用“完成编辑”的方法来完成编辑。

你可以通过处理表格触发的编辑事件来进一步地控制​​整个编辑过程。在编辑一个单元格的过程中,表格会触发以下一系列事件:

事件

描述

编辑前

一个可编辑的单元格被选中时会触发该事件。你可以通过将事件的“取消”参数设置为“真”来防止单元格被编辑。你还可以修改“组合列表”的属性,以便使适当的下拉按钮被画在单元格中。请注意,用户可能不会在这之后真正开始编辑,他可以简单地将选择移动到一个不同的单元格或控件。

开始编辑

除了用户已经在单元格中敲下了一个键或点击了下拉按钮并真正开始编辑以外,该事件与“编辑前”事件类似。你仍然可以在这一点上取消编辑。请注意,在这一点上“编辑器”属性仍然是空,因为该控件目前还没有确定应该使用的编辑器的类型。您可以在这一点上指定自定义编辑器到“编辑器”属性。

安装编辑器

该事件触发的时间是编辑器控件已经创建并且配置好去编辑该单元格之后,但在它被显示之前。在这一点上,你可以改变编辑器的属性(例如,在“文本框”编辑器中设置最大长度或密码字符)。你还可以将自己的事件处理程序添加到编辑器。

验证编辑

该事件触发的时间是当用户完成编辑且编辑器的值被复制回表格之前。你可以通过从表格中检索它来检查原始值 (该事件可以提供单元格的坐标)。你可以通过编辑器属性(例如,Editor.Text)来检查被分配到表格的新值。如果新的值对单元格无效,请将“取消”参数设置为“”,则表格将保持在编辑模式。相反,如果不想将单元格保持在编辑模式下,你最好还是恢复原来的值并离开编辑模式,设置“取消”为“”,然后使用“完成编辑”方法。

编辑后

该事件触发的时间是新的值已经被应用到单元格且编辑器已停用之后。你可以使用该事件来更新任何依赖于单元格值的东西(例如,分类汇总或排序)。

1.1.1 掩码

C1FlexGrid控件还支持屏蔽编辑。当用户输入时,这种类型的编辑可以使用一种输入掩码来提供一个模板,并自动验证该输入。该掩码由“编辑掩码”属性明确指定,它可以通过普通的文本字段和下拉组合区域来使用。

掩码字符串包括两种类型的字符:文字字符,这可以成为输入的一部分;模板字符,这是属于特定类别的占位字符(例如,数字或字母)。例如,下面的代码将一个编辑掩码“(999)999-9999”指定到第一列,该掩码包含的是电话号码,(数字“9”是一个可以代表任何数字的占位字符):

· Visual Basic

'建立一个电话号码的编辑掩码。

_flex.Cols(1).EditMask = "(999) 999-9999"

· C#

//建立一个电话号码的编辑掩码。

_flex.Cols[1].EditMask = "(999) 999-9999";

当你将“编辑掩码”属性设置为一个非空的字符串,会导致它必须使用内置的屏蔽编辑,即便该列包含日期/时间值(通常,一个“日期时间提取器”控件可以用于编辑这些列)。如果你有只含时间(没有日期)的“日期时间”列,这使用起来将格外方便。在这些情况下,你可以设置以下属性来使用一个屏蔽编辑器,而不是一个“日期时间提取器”控件:

· Visual Basic

flex.Cols(1).DataType = GetType(DateTime)

_flex.Cols(1).Format = "hh:mm tt"

_flex.Cols(1).EditMask = "99:99 LL"

· C#

flex.Cols[1].DataType = typeof(DateTime);

_flex.Cols[1].Format = "hh:mm tt";

_flex.Cols[1].EditMask = "99:99 LL";

你也可以在设计时通过使用“输入掩码”对话框来设置“编辑掩码”属性。

image

要访问输入掩码对话框可通过以下两种途经,“列任务”菜单或C1FlexGrid列编辑器

· 进入“列任务”菜单,在编辑掩码框中单击省略号按钮。

· 进入C1FlexGrid列编辑器,找到左窗格中的编辑掩码属性,并单击它旁边的省略号按钮。

注意:输入掩码对话框是特定的列,并且只会更改所选定的列的编辑掩码属性。

有关建立掩码字符串的语法的详细信息,请参阅该控件参考资料部分的编辑掩码属性。

如果在同一列的不同单元格需要不同的掩码,需要捕获编辑前事件,并为当前单元格将编辑掩码属性设置一个的适当的值。

1.1.2 验证

在许多情况下,为确保用户的数据输入是有效的,只有编辑掩码是不够的。例如,掩码不会让你指定一个可能值的范围,或以另一个单元格的内容为基础来验证当前单元格。

在这些情况下,需要捕获验证编辑事件,看看在“编辑器-文本”属性中包含的值是不是当前单元格的有效条目(在这一点上,单元格仍然有它的原始值)。如果该输入的是无效的,将“取消”参数设置为“”,表格将保持编辑模式直到用户输入一个有效的条目。

例如,将下面的代码验证输入到一个货币列,以确保输入的值处于1000和10000之间:

· Visual Basic

Private Sub _flex_ValidateEdit(ByVal sender As Object, ByVal e As

C1.Win.C1FlexGrid.ValidateEditEventArgs) Handles _flex.ValidateEdit

'验证金额。

If _flex.Cols(e.Col).DataType Is GetType(Decimal) Then

Try

Dim dec As Decimal = Decimal.Parse(_flex.Editor.Text())

If (dec < 1000) Or (dec > 10000) Then

MessageBox.Show("Value must be between 1,000 and 10,000")

e.Cancel = True

End If

Catch

MessageBox.Show("Value not recognized as a Currency")

e.Cancel = True

End Try

End If

End Sub

· C#

private void _flex_ValidateEdit( object sender, ValidateEditEventArgs e)

{

//验证金额。

if (_flex.Cols[e.Col].DataType == typeof(Decimal))

{

try

{

Decimal dec = Decimal.Parse(_flex.Editor.Text);

if ( dec < 1000 || dec > 10000 ) {

MessageBox.Show("Value must be between 1,000 and 10,000");

e.Cancel = true;

}

}

catch

{

MessageBox.Show("Value not recognized as a Currency");

e.Cancel = true;

}

}

}

1.1.3 自定义编辑器

内置的编辑器可以具备很大的灵活性和能力,但在某些情况下,你可能要使用外部控件作为专门的编辑器。例如,你可能想使用提供了一个下拉计算器的C1NumericInput控件来输入数字,或使用一个编辑器来从多列的列表中进行选择,或你可以用自己写的一个专门的控件来编辑你的业务对象。

从基本的“控件”类型派生出的任何控件都可以作为一个基本的表格编辑器使用。实现了IC1EmbeddedEditor接口(在C1.Common.dll的定义)的控件可以用表格提供更好的整合和更先进的功能。有关IC1EmbeddedEditor接口的更多详细信息,请参阅“编辑属性”。

要将一个控件作为自定义编辑器来使用,所有你必须要做的就是使用其“编辑”属性将控件的一个实例与一个表格列或一个样式关联到一起。你可以在设计器(使用列编辑器)或在代码中实现这步操作。在此之后,表格将自动使用该控件。

要在设计时定义自定义编辑器,先要将编辑器控件的一个实例添加到窗体,然后从C1FlexGrid任务菜单上选择设计器来打开C1FlexGrid列编辑器。选择应使用自定义编辑器的列,并将其编辑器的属性设置为新的编辑器控件的名称。

例如,要将NumericUpDown控件作为一个表格编辑器使用,请按照下列步骤操作:

1. 添加一个C1FlexGrid控件到窗体。

2. 将NumericUpDown控件添加到窗体,并将其“边框样式”属性设置为“”。

3. 从C1FlexGrid任务菜单上选择设计器。有关访问C1FlexGrid列编辑器的更多详细信息,请参阅“访问C1FlexGrid的列编辑器”(第143页)。

4. 在C1FlexGrid列编辑器上,选择第一个滚动的表格列,并将它的“编辑器”属性设置到NumericUpDown1

运行该项目并编辑第一列中的一些值。请注意表格如何定位和初始化NumericUpDown控件,以便你可以编辑单元格的值。当你完成对一个单元格的编辑,单击不同的单元格或按TAB键来移动到下一个。请注意新的值是如何应用到单元格的。

你也可以使用代码来给表格指定自定义编辑器:

· Visual Basic

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles MyBase.Load

'创建自定义编辑器。

Dim editor as New NumericUpDown()

editor.BorderStyle = BorderStyle.None

' 将自定义编辑器分配到表格。

_flex.Cols(1).Editor = editor

End Sub

· C#

private void Form1_Load(object sender, System.EventArgs e)

{

//创建自定义编辑器。

NumericUpDown editor = new NumericUpDown();

editor.BorderStyle = BorderStyle.None;

// 将自定义编辑器分配到表格。

_flex.Cols[1].Editor = editor;

}

创建自定义编辑器

从Control基类派生出的任何控件都可以用来作为一个表格编辑器使用。这是完全有可能的,因为在访问诸如“文本”和“界限”之类的属性,或诸如“请假”和“文本变更”之类的事件时,表格对基类控件有足够的了解。在很多情况下,这种程度的支持就足够了。

然而,在某些情况下,你可能想使用一些不那么密切地遵守基类的控件。例如,“日期时间提取器”控件有一个“”属性,它应该用来检索编辑过的值,而不是文本的值。在这些情况下,你可以在IC1EmbeddedEditor接口上实现一个或多个方法来覆盖默认的行为。例如,在C1Input库中所有控件都支持IC1EmbeddedEditor,因此,它与C1FlexGrid(还有C1TrueDBGrid)整合密切。

IC1EmbeddedEditor接口相当简单,并且由于表格是使用后期绑定与之相结合的,你甚至不需要实现其所有成员。只需要落实那个对你的编辑器控件有意义的即可。

接口确实提供了足够的灵活性来使几乎所有的控件都能作为一个表格编辑器使用。你甚至可以使用UITypeEditor这些类型来作为表格编辑器。要做到这一点,你需要一个包装类:

1. 派生于Control(UITypeEditor不可以)。

2. 实现IC1EmbeddedEditor接口。

3. 封装相应的UITypeEditor。

我们在CustomEditors样品中为这个包装类提供的源代码。

使用UITypeEditor包装类,你可以与C1FlexGrid一起使用任何UITypeEditors。.NET可以为编辑颜色,字体,文件名等提供几个UITypeEditors。你也可以自己写UITypeEditors,在某些情况下,这比写控件容易。

可用的示例项目

例如与C1FlexGrid一起使用内置的、自定义的和UITypeEditor编辑器,请在ComponentOne 帮助中心上参阅“自定义编辑器”样本。

1.1.4 编辑模式

你可以通过阅读编辑属性值来确定表格是否处于编辑模式。如果这个属性恢复为“无效”,则表格不是在编辑模式。不然,属性恢复一个引用值到正在用于编辑该单元格的控件(该控件可能是一个“文本框”,一个“组合框”,或其他类型的控件),表格就是处于编辑模式。你可以“开始编辑”的方法将表格程式化地设定在编辑模式下,并使用“完成编辑”的方法来完成编辑。

你可以通过处理表格触发的编辑事件来进一步地控制​​整个编辑过程。在编辑一个单元格的过程中,表格会触发以下一系列事件:

事件

描述

编辑前

一个可编辑的单元格被选中时会触发该事件。你可以通过将事件的“取消”参数设置为“真”来防止单元格被编辑。你还可以修改“组合列表”的属性,以便使适当的下拉按钮被画在单元格中。请注意,用户可能不会在这之后真正开始编辑,他可以简单地将选择移动到一个不同的单元格或控件。

开始编辑

除了用户已经在单元格中敲下了一个键或点击了下拉按钮并真正开始编辑以外,该事件与“编辑前”事件类似。你仍然可以在这一点上取消编辑。请注意,在这一点上“编辑器”属性仍然是空,因为该控件目前还没有确定应该使用的编辑器的类型。您可以在这一点上指定自定义编辑器到“编辑器”属性。

安装编辑器

该事件触发的时间是编辑器控件已经创建并且配置好去编辑该单元格之后,但在它被显示之前。在这一点上,你可以改变编辑器的属性(例如,在“文本框”编辑器中设置最大长度或密码字符)。你还可以将自己的事件处理程序添加到编辑器。

验证编辑

该事件触发的时间是当用户完成编辑且编辑器的值被复制回表格之前。你可以通过从表格中检索它来检查原始值 (该事件可以提供单元格的坐标)。你可以通过编辑器属性(例如,Editor.Text)来检查被分配到表格的新值。如果新的值对单元格无效,请将“取消”参数设置为“”,则表格将保持在编辑模式。相反,如果不想将单元格保持在编辑模式下,你最好还是恢复原来的值并离开编辑模式,设置“取消”为“”,然后使用“完成编辑”方法。

编辑后

该事件触发的时间是新的值已经被应用到单元格且编辑器已停用之后。你可以使用该事件来更新任何依赖于单元格值的东西(例如,分类汇总或排序)。

1.1.1 掩码

C1FlexGrid控件还支持屏蔽编辑。当用户输入时,这种类型的编辑可以使用一种输入掩码来提供一个模板,并自动验证该输入。该掩码由“编辑掩码”属性明确指定,它可以通过普通的文本字段和下拉组合区域来使用。

掩码字符串包括两种类型的字符:文字字符,这可以成为输入的一部分;模板字符,这是属于特定类别的占位字符(例如,数字或字母)。例如,下面的代码将一个编辑掩码“(999)999-9999”指定到第一列,该掩码包含的是电话号码,(数字“9”是一个可以代表任何数字的占位字符):

· Visual Basic

'建立一个电话号码的编辑掩码。

_flex.Cols(1).EditMask = "(999) 999-9999"

· C#

//建立一个电话号码的编辑掩码。

_flex.Cols[1].EditMask = "(999) 999-9999";

当你将“编辑掩码”属性设置为一个非空的字符串,会导致它必须使用内置的屏蔽编辑,即便该列包含日期/时间值(通常,一个“日期时间提取器”控件可以用于编辑这些列)。如果你有只含时间(没有日期)的“日期时间”列,这使用起来将格外方便。在这些情况下,你可以设置以下属性来使用一个屏蔽编辑器,而不是一个“日期时间提取器”控件:

· Visual Basic

flex.Cols(1).DataType = GetType(DateTime)

_flex.Cols(1).Format = "hh:mm tt"

_flex.Cols(1).EditMask = "99:99 LL"

· C#

flex.Cols[1].DataType = typeof(DateTime);

_flex.Cols[1].Format = "hh:mm tt";

_flex.Cols[1].EditMask = "99:99 LL";

你也可以在设计时通过使用“输入掩码”对话框来设置“编辑掩码”属性。

要访问输入掩码对话框可通过以下两种途经,“列任务”菜单或C1FlexGrid列编辑器

· 进入“列任务”菜单,在编辑掩码框中单击省略号按钮。

· 进入C1FlexGrid列编辑器,找到左窗格中的编辑掩码属性,并单击它旁边的省略号按钮。

注意:输入掩码对话框是特定的列,并且只会更改所选定的列的编辑掩码属性。

有关建立掩码字符串的语法的详细信息,请参阅该控件参考资料部分的编辑掩码属性。

如果在同一列的不同单元格需要不同的掩码,需要捕获编辑前事件,并为当前单元格将编辑掩码属性设置一个的适当的值。

1.1.2 验证

在许多情况下,为确保用户的数据输入是有效的,只有编辑掩码是不够的。例如,掩码不会让你指定一个可能值的范围,或以另一个单元格的内容为基础来验证当前单元格。

在这些情况下,需要捕获验证编辑事件,看看在“编辑器-文本”属性中包含的值是不是当前单元格的有效条目(在这一点上,单元格仍然有它的原始值)。如果该输入的是无效的,将“取消”参数设置为“”,表格将保持编辑模式直到用户输入一个有效的条目。

例如,将下面的代码验证输入到一个货币列,以确保输入的值处于1000和10000之间:

· Visual Basic

Private Sub _flex_ValidateEdit(ByVal sender As Object, ByVal e As

C1.Win.C1FlexGrid.ValidateEditEventArgs) Handles _flex.ValidateEdit

'验证金额。

If _flex.Cols(e.Col).DataType Is GetType(Decimal) Then

Try

Dim dec As Decimal = Decimal.Parse(_flex.Editor.Text())

If (dec < 1000) Or (dec > 10000) Then

MessageBox.Show("Value must be between 1,000 and 10,000")

e.Cancel = True

End If

Catch

MessageBox.Show("Value not recognized as a Currency")

e.Cancel = True

End Try

End If

End Sub

· C#

private void _flex_ValidateEdit( object sender, ValidateEditEventArgs e)

{

//验证金额。

if (_flex.Cols[e.Col].DataType == typeof(Decimal))

{

try

{

Decimal dec = Decimal.Parse(_flex.Editor.Text);

if ( dec < 1000 || dec > 10000 ) {

MessageBox.Show("Value must be between 1,000 and 10,000");

e.Cancel = true;

}

}

catch

{

MessageBox.Show("Value not recognized as a Currency");

e.Cancel = true;

}

}

}

1.1.3 自定义编辑器

内置的编辑器可以具备很大的灵活性和能力,但在某些情况下,你可能要使用外部控件作为专门的编辑器。例如,你可能想使用提供了一个下拉计算器的C1NumericInput控件来输入数字,或使用一个编辑器来从多列的列表中进行选择,或你可以用自己写的一个专门的控件来编辑你的业务对象。

从基本的“控件”类型派生出的任何控件都可以作为一个基本的表格编辑器使用。实现了IC1EmbeddedEditor接口(在C1.Common.dll的定义)的控件可以用表格提供更好的整合和更先进的功能。有关IC1EmbeddedEditor接口的更多详细信息,请参阅“编辑属性”。

要将一个控件作为自定义编辑器来使用,所有你必须要做的就是使用其“编辑”属性将控件的一个实例与一个表格列或一个样式关联到一起。你可以在设计器(使用列编辑器)或在代码中实现这步操作。在此之后,表格将自动使用该控件。

要在设计时定义自定义编辑器,先要将编辑器控件的一个实例添加到窗体,然后从C1FlexGrid任务菜单上选择设计器来打开C1FlexGrid列编辑器。选择应使用自定义编辑器的列,并将其编辑器的属性设置为新的编辑器控件的名称。

例如,要将NumericUpDown控件作为一个表格编辑器使用,请按照下列步骤操作:

1. 添加一个C1FlexGrid控件到窗体。

2. 将NumericUpDown控件添加到窗体,并将其“边框样式”属性设置为“”。

3. 从C1FlexGrid任务菜单上选择设计器。有关访问C1FlexGrid列编辑器的更多详细信息,请参阅“访问C1FlexGrid的列编辑器”(第143页)。

4. 在C1FlexGrid列编辑器上,选择第一个滚动的表格列,并将它的“编辑器”属性设置到NumericUpDown1

运行该项目并编辑第一列中的一些值。请注意表格如何定位和初始化NumericUpDown控件,以便你可以编辑单元格的值。当你完成对一个单元格的编辑,单击不同的单元格或按TAB键来移动到下一个。请注意新的值是如何应用到单元格的。

你也可以使用代码来给表格指定自定义编辑器:

· Visual Basic

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles MyBase.Load

'创建自定义编辑器。

Dim editor as New NumericUpDown()

editor.BorderStyle = BorderStyle.None

' 将自定义编辑器分配到表格。

_flex.Cols(1).Editor = editor

End Sub

· C#

private void Form1_Load(object sender, System.EventArgs e)

{

//创建自定义编辑器。

NumericUpDown editor = new NumericUpDown();

editor.BorderStyle = BorderStyle.None;

// 将自定义编辑器分配到表格。

_flex.Cols[1].Editor = editor;

}

创建自定义编辑器

从Control基类派生出的任何控件都可以用来作为一个表格编辑器使用。这是完全有可能的,因为在访问诸如“文本”和“界限”之类的属性,或诸如“请假”和“文本变更”之类的事件时,表格对基类控件有足够的了解。在很多情况下,这种程度的支持就足够了。

然而,在某些情况下,你可能想使用一些不那么密切地遵守基类的控件。例如,“日期时间提取器”控件有一个“”属性,它应该用来检索编辑过的值,而不是文本的值。在这些情况下,你可以在IC1EmbeddedEditor接口上实现一个或多个方法来覆盖默认的行为。例如,在C1Input库中所有控件都支持IC1EmbeddedEditor,因此,它与C1FlexGrid(还有C1TrueDBGrid)整合密切。

IC1EmbeddedEditor接口相当简单,并且由于表格是使用后期绑定与之相结合的,你甚至不需要实现其所有成员。只需要落实那个对你的编辑器控件有意义的即可。

接口确实提供了足够的灵活性来使几乎所有的控件都能作为一个表格编辑器使用。你甚至可以使用UITypeEditor这些类型来作为表格编辑器。要做到这一点,你需要一个包装类:

1. 派生于Control(UITypeEditor不可以)。

2. 实现IC1EmbeddedEditor接口。

3. 封装相应的UITypeEditor。

我们在CustomEditors样品中为这个包装类提供的源代码。

使用UITypeEditor包装类,你可以与C1FlexGrid一起使用任何UITypeEditors。.NET可以为编辑颜色,字体,文件名等提供几个UITypeEditors。你也可以自己写UITypeEditors,在某些情况下,这比写控件容易。

可用的示例项目

例如与C1FlexGrid一起使用内置的、自定义的和UITypeEditor编辑器,请在ComponentOne 帮助中心上参阅“自定义编辑器”样本。

1.1.4 编辑模式

你可以通过阅读编辑属性值来确定表格是否处于编辑模式。如果这个属性恢复为“无效”,则表格不是在编辑模式。不然,属性恢复一个引用值到正在用于编辑该单元格的控件(该控件可能是一个“文本框”,一个“组合框”,或其他类型的控件),表格就是处于编辑模式。你可以“开始编辑”的方法将表格程式化地设定在编辑模式下,并使用“完成编辑”的方法来完成编辑。

你可以通过处理表格触发的编辑事件来进一步地控制​​整个编辑过程。在编辑一个单元格的过程中,表格会触发以下一系列事件:

事件

描述

编辑前

一个可编辑的单元格被选中时会触发该事件。你可以通过将事件的“取消”参数设置为“真”来防止单元格被编辑。你还可以修改“组合列表”的属性,以便使适当的下拉按钮被画在单元格中。请注意,用户可能不会在这之后真正开始编辑,他可以简单地将选择移动到一个不同的单元格或控件。

开始编辑

除了用户已经在单元格中敲下了一个键或点击了下拉按钮并真正开始编辑以外,该事件与“编辑前”事件类似。你仍然可以在这一点上取消编辑。请注意,在这一点上“编辑器”属性仍然是空,因为该控件目前还没有确定应该使用的编辑器的类型。您可以在这一点上指定自定义编辑器到“编辑器”属性。

安装编辑器

该事件触发的时间是编辑器控件已经创建并且配置好去编辑该单元格之后,但在它被显示之前。在这一点上,你可以改变编辑器的属性(例如,在“文本框”编辑器中设置最大长度或密码字符)。你还可以将自己的事件处理程序添加到编辑器。

验证编辑

该事件触发的时间是当用户完成编辑且编辑器的值被复制回表格之前。你可以通过从表格中检索它来检查原始值 (该事件可以提供单元格的坐标)。你可以通过编辑器属性(例如,Editor.Text)来检查被分配到表格的新值。如果新的值对单元格无效,请将“取消”参数设置为“”,则表格将保持在编辑模式。相反,如果不想将单元格保持在编辑模式下,你最好还是恢复原来的值并离开编辑模式,设置“取消”为“”,然后使用“完成编辑”方法。

编辑后

该事件触发的时间是新的值已经被应用到单元格且编辑器已停用之后。你可以使用该事件来更新任何依赖于单元格值的东西(例如,分类汇总或排序)。

posted @ 2012-12-12 07:55  葡萄城开发工具  阅读(2377)  评论(2编辑  收藏  举报