标签:自身 bae order tor change 实现 用户 重写 子类
介绍 Pickers库是一个。net Windows控件库,用于帮助创建挑选样式的控件。 背景 什么是“选择器”控件? “选择器”控件可以看作是一个控件,它允许您从丰富的下拉UI中选择一个值,而不是简单的列表。例如,我们有DateTimePicker控件。类似的,Microsoft®Word中的颜色选择器就是一个选择器的例子。 . net窗体PropertyGrid控件使用许多不同类型的丰富下拉框来显示属性的值选项。例如: 在PropertyGrid之外,选择日期和时间的接口是常见的,可以作为DateTimePicker控件使用(如前所述)。但是如果我们想要PropertyGrid之外的其他接口呢? 本文选择器 Palo Mraz在他的ColorPicker和ColorPicker Revisited文章中对上述问题给出了神奇的答案。他描述了如何通过利用Windows窗体设计时基础设施在普通控件中托管颜色选择界面来模拟PropertyGrid的行为。在继续之前,请阅读原始的ColorPicker文章。Palo Mraz讨论的技术可以应用于托管我们控制范围内的任何其他UITypeEditor。对于每个UITypeEditor,从UITypeEditor中调用下拉选择UI的代码或多或少是相同的。 定制的拉ui 有时,对于PropertyGrid中特定类型的值,我们可能找不到一个很酷的下拉UI。在这种情况下,我们可以构建自己的UI并在不使用UITypeEditor后代的情况下显示它。 Palo Mraz讨论了在屏幕上保持下拉UI“holder”表单的正确方法,他的颜色选择器实现包含了在屏幕上正确定位下拉holder的代码。此代码还可以用于显示定制的UI。 泛化 我使用泛型对这段代码进行了一般化。用于管理控件的外观和行为的代码已经放在了一个地方。因此,要创建一个选择器,我们只需要创建一个下拉列表或找到一个UITypeEditor,它为我们提供了一个。 里面的代码 IDropDownUI,ISyncDropDownUI接口 这些接口定义了PickerBase类用于显示下拉列表并从中检索所选值的基本方法。ISyncDropDownUI接口添加UpdatePicker事件来更新选择器控件中的值,而不必控制显示。 PickerBase类 隐藏,复制Code
public abstract class PickerBase<T, U> : Control where U : Control, IDropDownUI, new()
这是选择器控件的最终基类。T为选择器的值(从下拉UI中选择的值)指定。net类型。U指定显示下拉选择UI的控件的。net类型。它必须实现IDropDownUI接口,该接口要求它实现方法GetSelectedValue和SetSeletedValue,以便选择器能够以正确的默认值下拉UI。它还实现了CloseDropDown事件,这是一个信号,表明用户已经选择了值,并且必须关闭下拉列表。它还可以实现ISyncDropDownUI接口来添加UpdatePicker事件。 存储所选值 类型T的私有成员_value存储选择器的值。通过Value属性以编程方式访问它。SetValueCore方法执行存储值、设置控件行为和根据值显示的任务。当该值通过用户选择或编程方式更改时,将引发ValueChanged事件。有一个抽象的GetDefaultValue方法,必须重写该方法,以便为控件提供一个动态默认值,以实现适当的设计时行为。 外观 选择器的外观是使用适配器模型管理的,就像Palo Mraz在ColorPicker Revisited中所做的那样。IPickerDisplayAdapter接口用于创建一个显示适配器,该适配器提供任何控件作为选择器的外观。它与显示控件交互,并使用下拉事件告诉选择器何时显示下拉。它还允许选择器使用OwnerDrawText和DrawIcon事件做一些自定义呈现。选择器将dock设置为DockStyle.Full来显示这个控件。已经提供了一个名为PickerDisplayAdapter的抽象基类来简化实现。默认提供两个读取适配器ComboBoxDisplayAdapter(提供ComboBox和EditableComboBox外观)和CheckButtonDisplayAdapter(提供CheckButton外观)。有关更多信息,请参阅源代码。 注意:用于EditableComboBox外观的代码主要是Palo Mraz的实现,只是为了跟上我的“通用实现”而撒了一点小谎。 显示下拉 受保护成员DropDownHolder是对托管下拉UI的窗体窗口的引用。它的类型是DropDownForm,这是一个为托管定制的下拉UI或UI prov而设计的表单是由UITypeEditor编辑的。(两者都以控制的形式存在。)当显示适配器引发下拉事件时,选择器调用ShowDropDown方法,该方法创建下拉UI控件(U)的实例,调用虚拟方法InitializeDropDownControl(U控件)来让子类执行自定义初始化,并使用DoDropDown方法在屏幕上显示它。当用户选择一个值时,下拉UI会引发CloseDropDown事件,选择器会强制关闭DropDownHolder。如果用户取消选择,DropDownHolder将关闭自身,并告诉选择器选择已被取消。 SvcPickerBase类 隐藏,复制Code
public abstract class SvcPickerBase<T, E> : PickerBase<T, SvcPickerBaseUI> where E : UITypeEditor, new()
SvcPickerBase类用于宿主来自UITypeEditors的选择ui。只需在E类型参数中指定UITypeEditor后代的。net类型,就可以看到神奇的效果了! 由于SvcPickerBase不再需要自定义构建的UI,这个功能使用一个虚拟的SvcPickerBaseUI类隐藏。 SvcPickerBase。PickerEditorService类 隐藏,复制Code
private class PickerEditorService<ST, SE> : IWindowsFormsEditorService, IServiceProvider where SE : UITypeEditor, new()
这个类通过实现IWindowsFormsEditorService接口和IServiceProvider接口,提供了在SvcPickerBase中托管UITypeEditor的服务。SvcPickerBase中的valueEditorService私有成员持有这个类的一个实例,以便它可以用于显示下拉列表。有关详细信息,请参阅Palo Mraz的ColorPicker。 在SvcPickerBase ShowDropDown () 这是对Palo Mraz的颜色选择器代码的继承。它覆盖了显示定制构建UI的过程,并用UITypeEditor提供的显示UI的方法替换它。它调用UITypeEditor后代的EditValue,将PickerEditorService类(valueEditorService)的实例和当前值传递给它。该方法使用实例来显示下拉选择UI。当用户选择一个值时,它向PickerEditorService发送关闭下拉列表的信号,而下拉列表又要求选择器关闭下拉列表表单。如果选择被取消,DropDownHolder将关闭自身,并告知PickerEditorService对象(以及选择器)选择已被取消。 使用的代码 使用PickerBase类 可以使用PickerBase类用最少的代码创建选择器控件。只需遵循以下步骤: 创建作为下拉UI的控件。更好的设计方式是,用户可以通过单点添加IDropDownUI接口的实现声明来选择值到下拉UI控件类中,添加一个RaiseCloseDropDown()方法和选择值成员,这样更方便: 隐藏,复制代码私有TypeName selectedValue; 私人空间RaiseCloseDropDown () { if (CloseDropDownHolder != null) CloseDropDownHolder(这个,EventArgs.Empty); } 实现GetSelectedValue()和SetSelectedValue(value)方法: 隐藏,复制Codeobject IDropDownUI.GetSelectedValue () { //确定所选值的代码(如果需要) 返回selectedValue; } void IDropDownUI。SetSelectedValue(对象值) { selectedValue = (TypeName)值; //根据值更新控件外观的代码 } 确保UI在用户选择发生变化时更新selectedValue变量,并在正确的时间调用RaiseCloseDropDown()。 注意:请看PickersDemo应用中的例子HorizontalAlignmentUI。 通过扩展PickerBase类创建主选择器控件类。由于PickerBase是一个泛型类,因此将picker值的类型和UI控件作为类型参数提供给它,就可以看到效果了。例如,你想为类型TypeName的值创建一个选择器,你的UI叫做TypeNameUI,然后: 隐藏,复制Codepublic类TypeNamePicker: PickerBase<TypeName, TypeNameUI> { GetDefaultValue() { 返回some_default_value; } } 注意:您必须重写GetDefaultValue方法,没有它,您的代码将无法编译,您的选择器控件将不能在设计器中正常运行。如果您想添加额外的功能,您可以覆盖其他方法(请参阅源代码以获得更多信息)。 如果实现了ISyncDropDownUI接口,则需要将UpdatePicker事件添加到实现中。选择器使用此事件更新其值,并首先关闭控件。因此,当控件中的选择发生更改时,可以引发此事件。 使用SvcPickerBase 使用SvcPickerBase要容易得多,因为它帮助您使用来自PropertyGrid的UI。找出您想要选择器获取的值的类型的类型编辑器的类名。然后只需继承SvcPickerBase,如下所示: 假设你想为类型TypeName和UITypeEditor后代的值创建一个选择器,你用来提供下拉UI称为TypeNameEditor,然后: 隐藏,复制Code
public class TypeNamePicker : SvcPickerBase<TypeName, TypeNameEditor> { protected override int HeightCorrection { get { // if the default UI provided by TypeNameEditor is // giving problems with height, // return some appropriate value here return 0; } } protected override TypeName GetDefaultValue() { return some_default_value; } protected override string FormatValue(TypeName value) { // format your value‘s string to display nicely here return InsertSpaces(base.FormatValue(value)); } }
的兴趣点 提供了一些示例选择器。请一定要看。 请报告任何错误、错误、关于代码/文章的建议、新特性,请参见CodeProject的文章。 历史 v2.1.0.0(2007年10月15日)——实现了EditableComboBoxDisplay类。添加ISyncDropDownUI接口(以添加UpdatePicker特性)。将InitializeDropDownControl和ValueFromString方法添加到PickerBase类。更新了文章以反映所有这些变化。v 2.0.0.0 -重写了这篇文章,使其更具描述性。添加了显示适配器支持,它添加了组合框、可编辑组合框和复选框按钮外观。v1.0.0.0——第一个版本(基本支持创建选择器,没有适配器模型,只有组合框外观) 本文转载于:http://www.diyabc.com/frontweb/news236.html
标签:自身 bae order tor change 实现 用户 重写 子类
原文地址:https://www.cnblogs.com/Dincat/p/13431248.html