まず、Collection<Control>
の代わりに使用しList<T>
ます。多くの場合、リストは機能しますが、望ましくない方法でコレクションを公開します。
context.Container.Components
既存のコントロールを取得するには、LoadValues
オーバーライドを掘り下げる必要があります。ホストフォーム自体とコンポーネントを含むすべてが含まれているため、それらをフィルタリングする必要がある可能性があります. DataGridViewColumns
確かなことの 1 つは、コンポーネント (や など)を削除することTabPages
です。これは、コントロールのリストまたはコレクションに入らないためです。TableLayoutPanels などの他のものも削除することがよくあります。
このバージョンでは、デフォルトのドロップダウンの一部のコンポーネントとコントロールが除外されています。
protected override void LoadValues(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
{
bool bAdd = true;
Control thisCtl = null;
Collection<Control> tCollection = (Collection<Control>)value;
foreach (object obj in context.Container.Components) {
//Cycle through the components owned by the form in the designer
bAdd = true;
// exclude other components - this weeds out DataGridViewColumns which
// can only be used by a DataGridView
if (obj is Control) {
thisCtl = (Control)obj;
if (ExcludeForm) {
bAdd = !(thisCtl is Form);
}
// custom exclude list
if ((typeExclude != null) && (typeExclude.Count > 0)) {
if (typeExclude.Contains(thisCtl.GetType)) {
bAdd = false;
}
}
bool bCheck = false;
int ndx = 0;
if (bAdd) {
bCheck = tCollection.Contains(thisCtl);
ndx = myCtl.Items.Add(new ListItem(thisCtl));
myCtl.SetItemChecked(ndx, bCheck);
}
}
}
}
必要に応じて、適切なコントロールのダイアログ スタイルを表示し、ユーザーがコントロールを選択できるように CheckedListBox を使用できます。詳細については、CodeProject Selecting Form's Controls at Design Timeに関する記事があります。
これは VB で作成されていますが、このような野獣を簡単に実装することができます (私が書いたので、偏見があるかもしれません)。
ExampleDropDownControlCollectionUIEditor : ControlCollectionDropDownUIEditor
{
public ExampleDropDownControlCollectionUIEditor() : base()
{
base.ExcludeForm = true;
base.CheckControlWidth = 200;
base.typeExclude.Add(typeof(RadioButton));
base.typeExclude.Add(typeof(Label));
}
}
ダイアログフォームはシンプルで、別の基本クラスを使用するだけで、ControlCollectionDialogUIEditor