返回首页

{S0}简介
选择器库。NET Windows控件库在创建选择器式控制艾滋病。背景什么是"选择器"控制?
A"选择器"的控制,可以认为是作为控制,它允许您选择从丰富,用户界面​​,而不是一个简单的列表下拉的价值。例如,我们在DateTimePicker控制。同样,在微软??字的颜色选择器是一个选择器的一个例子。
。NET Windows窗体PropertyGrid控制使用许多不同种类丰富的下拉式提交属性值选项。例如:
选择的日期和时间的接口是常见的外DateTimePicker控件(如前所述)PropertyGrid中提供给我们。但是,如果我们想PropertyGrid的一些其他的接口?ColorPicker的文章
的Palo Mraz给他{A}对上述问题的一个神奇的答案,然后再继续。帕洛阿尔托Mraz讨论该技术可以应用到主机内我们所能控制的的任何其他UITypeEditor的。调用的UITypeEditor的下拉选择的UI代码是或多或少每UITypeEditor的相同。定制掉​​落下来的UI
有时候,我们可能无法找到一个特定类型的价值在PropertyGrid凉爽的下拉UI。在这种情况下,我们可以建立我们自己的用户界面,并显示它不使用UITypeEditor的后裔。
的Palo Mraz讨论保持下拉UI"的持有人"在屏幕上形成正确的方法,和他的ColorPicker的实施包含定位在屏幕上正确的下拉持有人的代码。此代码也可用于显示定制的UI。概括
我有广义此代码使用泛型。代码管理控制的外观和行为已经在一个地方。所以,要创建一个选择器,我们只需要创建一个致力于下降下降,或发现,为我们提供了一个UITypeEditor的。里面的代码IDropDownUI放大器; ISyncDropDownUI接口
这些接口定义PickerBase类用于显示下拉,并从中检索选定的值的基本方法。 ISyncDropDownUI接口添加UpdatePicker事件更新,而无需控制显示在选择器控制的价值。PickerBase类

public abstract class PickerBase<T, U>

    : Control where U : Control, IDropDownUI, new()

这是一个选择器控制的最终基类。 T规定为选择器的值(从下拉用户界面选择)。NET类型。 U指定呈现下拉选择UI控制。NET类型。它必须实现,这就要求实施方法GetSelectedValue和SetSeletedValue IDropDownUI接口,使机械手可以用正确的默认UI的下拉。它还实现了CloseDropDown事件,这是一个信号,用户选择的价值和下拉,必须关闭。可选的,它也可以实现ISyncDropDownUI接口添加UpdatePicker事件。储存所选的值
一个名为_value,商店选择器的值类型T的私有成员。它是通过编程访问Value属性。 SetValueCore方法存储的价值和设置控制行为的任务,并显示值。当此值变化可以由用户选择或编程,引发ValueChanged事件。有是一个抽象的GetDefaultValue的方法,必须重写,以提供一个动态的默认值,控制适当的设计时行为。外观
选择器的外观是管理使用。 IPickerDisplayAdapter接口是用来创建一个显示适配器提供作为选择器的外观任何控制。交互与显示控制,并告诉选择器时,以显示下拉使用DropDown事件。它还允许选择器使用OwnerDrawText和DrawIcon事件做了一些自定义呈现。选择器显示这与码头的控制设置为DockStyle.Full。已经提供了一个抽象基类称为PickerDisplayAdapter便于实施。两个读适配器ComboBoxDisplayAdapter(提供ComboBox和EditableComboBox出场)和CheckButtonDisplayAdapter(提供CheckButton外观)默认情况下提供。欲了解更多信息,请参见源代码。注:EditableComboBox外观的代码主要是一点点fibbing保持我的"通用实施"的Palo Mraz的实施。显示下拉
受保护的成员DropDownHolder是主机的用户界面下拉表单窗口的引用。它的类型DropDownForm,这是主办定制的下拉式UI或UITypeEditor的提供UI设计了一个表格。 (两者都是控制的形式。)显示适配器引发DropDown事件时,采集器调用ShowDropDown的方法,它创建一个下拉的UI控制(美)实例,调用虚方法InitializeDropDownControl(ü控制)让子类执行自定义初始化,并显示在屏幕使用DoDropDown方法。当用户选择一个值,拖放式用户界面提高了CloseDropDown事件,并选择器强制DropDownHolder被关闭。如果用户取消选择,DropDownHolder关闭本身并告诉被取消选择选择器。SvcPickerBase类{C}
SvcPickerBase类是用于主机UITypeEditors选择用户界面。只要指定的E型参数的UITypeEditor的后裔。NET类型和看到的神奇!
作为SvcPickerBase不再需要建一个自定义的UI,这个功能是使用一个虚拟的SvcPickerBaseUI类隐藏。SvcPickerBase.PickerEditorService类
private class PickerEditorService<ST, SE>

    : IWindowsFormsEditorService, IServiceProvider where SE : 

    UITypeEditor, new()

这个类提供托管内SvcPickerBase UITypeEditor的,通过实施IWindowsFormsEditorService接口和IServiceProvider接口的服务。 SvcPickerBase valueEditorService在私有成员认为这个类的一个实例,因此它可用于显示下拉。有关详情,请参阅。ShowDropDown()在SvcPickerBase
这是一个结转的Palo Mraz的ColorPicker的代码。它覆盖了显示一个自定义生成UI的过程,并显示所UITypeEditor的提供的用户界面的方法取代它。它调用的EditValue PickerEditorService类(valueEditorService)和当前值的一个实例传递给它的UITypeEditor的后裔。该方法使用的实例,以显示下拉选择的用户界面。当用户选择一个值,它的信号PickerEditorService关闭下拉,这反过来又要求选择器关闭下拉型窗体。如果选择取消,DropDownHolder关闭本身,并告诉PickerEditorService对象(因此选择器),选择取消。使用代码使用PickerBase类
PickerBase类可用于创建与最少量的代码选择器控制。只要遵循以下步骤:创建一个控件,下拉UI。这是更好地设计,这样用户可以选择一个单"的价值执行下拉UI控件类声明为IDropDownUI接口添加RaiseCloseDropDown()方法和选定的值成员,为您缓解:
private TypeName selectedValue;



private void RaiseCloseDropDown()

{

    if (CloseDropDownHolder != null)

        CloseDropDownHolder(this, EventArgs.Empty);

}
实施GetSelectedValue()和SetSelectedValue(值)的方法:
object IDropDownUI.GetSelectedValue()

{

    // code to determine selected value (if required)

    return selectedValue;

}



void IDropDownUI.SetSelectedValue(object value)

{

    selectedValue = (TypeName)value;

    // code to update your control's appearance based on value

}
确保您的UI更新为用户选择的变化的SelectedValue变量,并调用RaiseCloseDropDown(在正确的时间)。注:请参阅PickersDemo应用程序的例子Horizo​​ntalAlignmentUI。主要选取器控件类创建扩展PickerBase类。由于PickerBase是一个通用类,它的类型选择器的价值和你的用户界面控制类型参数见的神奇。例如,您要创建一个值类型typename和你的用户界面被称为TypeNameUI然后选择器:
public class TypeNamePicker : PickerBase<TypeName, TypeNameUI>

{

    protected override TypeName GetDefaultValue()



    {

        return some_default_value;

    }

}
注意:您必须重写GetDefaultValue方法,没有它你的代码将无法编译,你的选择器控制不会表现在设计师。如果你想添加其他功能,可以覆盖其它方法(参见更多信息的源代码)。如果要实现ISyncDropDownUI接口,那么你需要添加到您的执行UpdatePicker事件。选择器使用此事件来更新它的价值,与先关闭您的控制。所以,你可以提出这个事件时,在您的控制变化的选择。使用SvcPickerBase
使用SvcPickerBase时要容易得多,因为它帮助您使用PropertyGrid的UI。找出你想要的值的选择器类型的类型编辑器的类的名称。然后,只需继承SvcPickerBase如下所示:
假设你想创建一个类型typename和UITypeEditor的后裔的值选择器,您使用的用户界面被称为TypeNameEditor然后提供下拉: 兴趣点
已提供一些例如采摘。请不要看到它们。
在CodeProject的文章,请报告任何错误,错误代码/条建议,新的功能在这里。历史v 2.1.0.0(2007年10月15日,日) - 实施EditableComboBoxDisplay类。新增ISyncDropDownUI接口(添加UpdatePicker功能)。 InitializeDropDownControl和ValueFromString方法PickerBase类。更新的文章,以反映这些变化。v 2.0.0.0 - 重写更具描述性的文章。增加了显示适配器支持,增加了组合框,可编辑的组合框,复选框按钮的外观。 (这需要更多的重构,编码。) v 1.0.0.0 - 第一个版本(基本支持建立拾荒者没有适配器的型号,只有ComboBox的外观)

回答

评论会员:游客 时间:2011/12/14
喜微星。伟大的文章!看来,采摘,因为它们是不支持残疾人士的外观。我需要创建自己的自定义颜色选择器,我可以禁用和支持主题。我来支持这个主题的变化,我附上了一个统一的diff。我只是用你的"只读"的组合,所以,我已经改变了。这作品以及其他超过下列问题:1。在WindowsXP中,当使用"WindowsXP"的主题,ComboBoxRenderer.DrawTextBox绘制一个蓝色边框(而不是灰色)当通过ComboBoxState.Disabled。文本显示禁用。这是内置在组合框(在边境禁用太)不一致2。看来这个自定义组合框的外观是完全不同,在WindowsVista中正常的ComboBox的。ComboBoxRenderer少了点产品相同的组合,所以看起来是不相符的的(当你不使用"Windows经典"主题")我已经花了太多时间,就这样一件小事。我想我要离开它现在。如果任何人有任何建议,我会很感激他们。这里的差异:codepre---ComboBoxAppearance/ComboBoxDisplayBase.cs TueOctspanclass="code-digit"16/spanspanclass="code-digit"12/span:spanclass="code-digit"54/span:spanclass="code-digit"52/spanspanclass="code-digit"2007/span+++ComboBoxAppearance/ComboBoxDisplayBase.cs FriNovspanclass="code-digit"13/spanspanclass="code-digit"10/span:spanclass="code-digit"33/span:spanclass="code-digit"38/spanspanclass="code-digit"2009/span@@-107,spanclass="code-digit"6/span+107,spanclass="code-digit"7/span@@spanclass="code-SummaryComment"////spanspanclass="code-comment"spanclass="code-SummaryComment"</spanspanclass="code-SummaryComment"param/spanspanclass="code-SummaryComment"name="pe"/spanspanclass="code-SummaryComment">/spanAspanclass="code-SummaryComment"</spanspanclass="code-SummaryComment"see/spanspanclass="code-SummaryComment"cref="System.Windows.Forms.PaintEventArgs"/spanspanclass="code-SummaryComment"//spanspanclass="code-SummaryComment">/spanthatcontainstheeventdata.spanclass="code-SummaryComment"</spanspanclass="code-SummaryComment"//spanspanclass="code-SummaryComment"param/spanspanclass="code-SummaryComment">/span/spanspanclass="code-keyword"protected/spanspanclass="code-keyword"override/spanspanclass="code-keyword"void/spanOnPaint(PaintEventArgspe){+ComboBoxStatecomboState=(spanclass="code-keyword"this/span.Enabled?ComboBoxState.Normal:ComboBoxState.Disabled);spanclass="code-comment"///spanspanclass="code-comment"CallingthebaseclassOnPaint/spanspanclass="code-keyword"base/span.OnPaint(pe);@@-110,spanclass="code-digit"12/span+111,spanclass="code-digit"20/span@@spanclass="code-comment"///spanspanclass="code-comment"CallingthebaseclassOnPaint/spanspanclass="code-keyword"base/span.OnPaint(pe);+spanclass="code-comment"///spanspanclass="code-comment"cleareverything/span+spanclass="code-comment"///spanspanclass="code-comment"[12/11/2009]DJC:Thebackgroundofthecontrolneedstolooksdisabledtoo./span+spanclass="code-comment"///spanspanclass="code-comment"AlthoughIcouldn'tfindanydocumentationofthis.Itseemscomboboxesbackgroundcolor/span+spanclass="code-comment"///spanspanclass="code-comment"isdrawnasSystemColors.Controlwhentheyaredisabled./span+spanclass="code-keyword"if/span(spanclass="code-keyword"this/span.Enabled)pe.Graphics.Clear(BackColor);+spanclass="code-keyword"else/span+pe.Graphics.Clear(SystemColors.Control);spanclass="code-comment"///spanspanclass="code-comment"drawthecomboboxbehind,ifvisualstylesareenabledandavailable/span-spanclass="code-keyword"if/span((ComboBoxRenderer.IsSupported)&(Application.RenderWithVisualStyles))-ComboBoxRenderer.DrawTextBox(pe.Graphics,spanclass="code-keyword"this/span.ClientRectangle,ComboBoxState.Normal);+spanclass="code-comment"///spanspanclass="code-comment"[12/11/2009]DJCaddedinordertodrawdisabledtext+themesupport/span+spanclass="code-keyword"if/span((ComboBoxRenderer.IsSupported)&&(Application.RenderWithVisualStyles))+ComboBoxRenderer.DrawTextBox(pe.Graphics,spanclass="code-keyword"this/span.ClientRectangle,spanclass="code-keyword"this/span.Text,spanclass="code-keyword"this/span.Font,Rectangle.Truncate(spanclass="code-keyword"this/span.TextRectangle),comboState);spanclass="code-comment"///spanspanclass="code-comment"drawtheicon/spanspanclass="code-keyword"if/span(displayIcon)@@-126,spanclass="code-digit"11/span+135,spanclass="code-digit"13/span@@handler(spanclass="code-keyword"this/span,e);}-spanclass="code-comment"///spanspanclass="code-comment"drawthetext/span+spanclass="code-comment"///spanspanclass="code-comment"[12/11/2009]DJC/span+spanclass="code-keyword"if/span((!ComboBoxRenderer.IsSupported)||(!Application.RenderWithVisualStyles))spanclass="code-keyword"this/span.DrawTextArea(pe.Graphics);spanclass="code-comment"///spanspanclass="code-comment"drawthebutton/span-DrawButton(pe.Graphics,ComboBoxState.Normal);++DrawButton(pe.Graphics,comboState);spanclass="code-comment"///spanspanclass="code-comment"drawtheborderusingnormalControlPaint,ifvisualstylesarenotavailable./spanspanclass="code-keyword"if/span(!(ComboBoxRenderer.IsSupported)|!(Application.RenderWithVisualStyles))---ComboBoxAppearance/ReadonlyComboBoxDisplay.cs MonOctspanclass="code-digit"15/spanspanclass="code-digit"21/span:spanclass="code-digit"04/span:spanclass="code-digit"26/spanspanclass="code-digit"2007/span+++ComboBoxAppearance/ReadonlyComboBoxDisplay.cs ThuNovspanclass="code-digit"12/spanspanclass="code-digit"15/span:spanclass="code-digit"22/span:spanclass="code-digit"13/spanspanclass="code-digit"2009/span@@-77,spanclass="code-digit"7/span+77,spanclass="code-digit"11/span@@spanclass="code-comment"///spanspanclass="code-comment"br:TheBrushtousefordrawing./spanspanclass="code-keyword"private/spanspanclass="code-keyword"void/spanDrawText(Graphicsg,Brushbr){+spanclass="code-comment"///spanspanclass="code-comment"[12/11/2009]DJC/span+spanclass="code-keyword"if/span(spanclass="code-keyword"this/span.Enabled)g.DrawString(spanclass="code-keyword"this/span.Text,spanclass="code-keyword"this/span.Font,br,TextRectangle);+spanclass="code-keyword"else/span+ControlPaint.DrawStringDisabled(g,spanclass="code-keyword"this/span.Text,spanclass="code-keyword"this/span.Font,SystemColors.Control,TextRectangle,StringFormat.GenericDefault);}spanclass="code-SummaryComment"////spanspanclass="code-comment"spanclass="code-SummaryComment"</spanspanclass="code-SummaryComment"summary/spanspanclass="code-SummaryComment">/span/span---SvcPickerBase.cs SatAugspanclass="code-digit"25/spanspanclass="code-digit"19/span:spanclass="code-digit"35/span:spanclass="code-digit"32/spanspanclass="code-digit"2007/span+++SvcPickerBase.cs ThuNovspanclass="code-digit"12/spanspanclass="code-digit"15/span:spanclass="code-digit"39/span:spanclass="code-digit"06/spanspanclass="code-digit"2009/span@@-87,spanclass="code-digit"11/span+87,spanclass="code-digit"27/span@@spanclass="code-SummaryComment"////spanspanclass="code-comment"spanclass="code-SummaryComment"</spanspanclass="code-SummaryComment"//spanspanclass="code-SummaryComment"summary/spanspanclass="code-SummaryComment">/span/spanspanclass="code-keyword"protected/spanspanclass="code-keyword"override/spanspanclass="code-keyword"void/spanDrawIcon(Graphicsg,RectangleiconRectangle){+Eeditor=spanclass="code-keyword"new/spanE();spanclass="code-keyword"if/span(editor.GetPaintValueSupported()){+spanclass="code-comment"///spanspanclass="code-comment"[12/11/2009]DJC/span+spanclass="code-keyword"if/span(spanclass="code-keyword"this/span.Enabled){editor.PaintValue(Value,g,iconRectangle);g.DrawRectangle(Pens.Black,iconRectangle);+}spanclass="code-keyword"else/span{spanclass="code-comment"///spanspanclass="code-comment"drawthevaluedisabled/span+spanclass="code-keyword"using/span(Bitmapbmp=spanclass="code-keyword"new/spanBitmap(iconRectangle.Width+1,iconRectangle.Height+1)){+spanclass="code-keyword"using/span(GraphicsbmpG=Graphics.FromImage(bmp)){+RectanglenewRect=iconRectangle;+newRect.X=newRect.Y=spanclass="code-digit"0/span;+editor.PaintValue(Value,bmpG,newRect);+spanclass="code-comment"///spanspanclass="code-comment"Usegrayinsteadofblack,blackseemstoremainblackwhendisabled/span+bmpG.DrawRectangle(Pens.Gray,newRect);+ControlPaint.DrawImageDisabled(g,bmp,iconRectangle.X,iconRectangle.Y,SystemColors.Control);+}+}+}+}editor=spanclass="code-keyword"null/span;} /pre/code
会员1329368
评论会员:游客 时间:2011/12/14
dropdownbutton并没有显示在Vista中作为ComboBox的相同...你有任何计划,以修复它吗?3X
Laoujin
评论会员:游客 时间:2011/12/14
您好微星,我想,在工作中使用的一些你的代码,但我的经理问我,以确保我所使用的所有代码有相应的许可证。能否请您选择一个选择器库许可证。我找不到一个,只有一个版权声明。http://www.codeproject.com/info/Licenses.aspx最好,在CodeProject开放许可,但它是你的选择{S3}谢谢!托比亚斯
菲尔井
评论会员:游客 时间:2011/12/14
这是相当惊人的东西{S3}我需要实现这样的一个ToolStrip内的控制,所以我以为我只能嵌入在ToolStripControlHost中,它只是将工作。
菲尔井
评论会员:游客 时间:2011/12/14
这是伟大的东西,但EditableComboBox实施的情况下是真的杀了我现在。你期望能够提供的速度有多快?如果它要需要一段时间,你可以给我什么我需要做自己实现这个想法?我也建议你把一个DoInitialise(U控制)在ShowDropDown方法的PickerBase类的模板方法调用实例的控制和设置选定的值后。子类可以重写此方法,在DropDownUI做任何控件的自定义初始化,才显示给用户(例如,我有一个DropDownUI显示DataGrid中,需要这样的机制,让我设置的内容网格)。此外,您可能要考虑加入UpdatePicker事件的IDropDownUI接口,允许降下来的UI更新,恕不在选择器中显示的值,也不必关闭下拉。
zebulon75018
评论会员:游客 时间:2011/12/14
Thanx抽出时间给您的宝贵的思想。我将发布10月16日与EditableComboBoximplementaion。,这将包括所有这些宝贵的suggesstions。Thanx再次!{S3}此致微星{S3}
格雷格Cadmes
评论会员:游客 时间:2011/12/14
我提交了更新后的文件到CodeProject上。他们应在一段时间后。此致{S3}MSI