[英]C# Winforms Designer won't open because it cannot find type in same assembly
[英]C# Winforms Visual Studio designer cannot find custom type
我有一個帶有通用類型的自定義類型的自定義控件。 此列表是公共定義的:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Editor(typeof(ButtonPanelXEditor), typeof(UITypeEditor))]
public List<CompactButton> CompactButtons
{
get { return _compactButtons; }
set { _compactButtons = value; }
}
當我將此控件添加到表單並構建項目時,出現以下錯誤:
錯誤1找不到名稱的類型。 類型名稱為“ ButtonPanelX.CompactButton,ButtonPanelX,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null”。 127行,位置5。D:\\ Projecten \\ ButtonPanelX \\ ButtonPanelX \\ Form1.resx 127 5 ButtonPanelX
當我使用字符串而不是自定義對象時,設計器確實會保存我的列表。 CompactButton
具有[Serializable]
屬性,並從ISerializable
派生
我該怎么做才能解決此問題?
編輯:
public class ButtonPanelXEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
if (context != null && context.Instance != null)
// We will use a window for property editing.
return UITypeEditorEditStyle.Modal;
return base.GetEditStyle(context);
}
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context,
IServiceProvider provider, object value)
{
context.OnComponentChanging();
ButtonPanel b = context.Instance as ButtonPanel;
FooBar form = new FooBar();
form.Buttons = b.CompactButtons;
form.ShowDialog();
b.CompactButtons = form.Buttons;
b.DrawButtons();
context.OnComponentChanged();
return form.Buttons;
}
}
編輯2:
[Serializable]
public partial class ButtonPanel : UserControl
{
private ArrayList _compactButtons;
public ButtonPanel()
{
InitializeComponent();
_compactButtons = new ArrayList();
AddButtons();
this.Load += new EventHandler(ButtonPanel_Load);
}
void ButtonPanel_Load(object sender, EventArgs e)
{
DrawButtons();
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Editor(typeof(ButtonPanelXEditor), typeof(UITypeEditor))]
public ArrayList CompactButtons
{
get { return _compactButtons; }
}
public void DrawButtons()
{
baseButton1.Visible = ((CompactButton)_compactButtons[0]).Visible;
baseButton2.Visible = ((CompactButton)_compactButtons[1]).Visible;
}
private void AddButtons()
{
/* Buttons baseButton1 and baseButton2 are created by the designer */
CompactButton c = new CompactButton();
c.Enabled = baseButton1.Enabled;
c.Visible = baseButton1.Visible;
c.Name = baseButton1.Name;
CompactButton c2 = new CompactButton();
c2.Enabled = baseButton2.Enabled;
c2.Visible = baseButton2.Visible;
c2.Name = baseButton2.Name;
_compactButtons.Add(c);
_compactButtons.Add(c2);
}
}
您可以嘗試將按鈕序列化為后面的代碼,而不是將按鈕序列化為資源文件。 為此,您需要為您的CompactButton
類型實現自定義TypeDescriptor
,並在那里處理到InstanceDescriptor
轉換。 看一下如何實現TypeConverter 。 例:
[TypeConverter(typeof(CompactButtonTypeConverter))]
public class CompactButton: ... {
...
}
public class CompactButtonTypeConverter: TypeConverter {
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
if (destinationType == typeof(InstanceDescriptor))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
if (destinationType == typeof(InstanceDescriptor) && value is CompactButton) {
// This assumes you have a public default constructor on your type.
ConstructorInfo ctor = typeof(CompactButton).GetConstructor();
if (ctor != null)
return new InstanceDescriptor(ctor, new object[0], false);
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
有關更多信息,請參見InstanceDescriptor類。
更新 :至於您的UITypeEditor
和CompactButtons屬性,則不需要設置器。 更改您的CompactButtons屬性,如下所示:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Editor(typeof(ButtonPanelXEditor), typeof(UITypeEditor))]
public List<CompactButton> CompactButtons
{
get { return _compactButtons; } // _compactButtons must of course be initialized.
}
然后,您可以像這樣實現UITypeEditor
的EditValue方法:
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context,
IServiceProvider provider, object value) {
if (context == null || provider == null)
return null;
var b = context.Instance as ButtonPanel;
if (b == null)
return value;
var editorService = (IWindowsFormsEditorService)
provider.GetService(typeof(IWindowsFormsEditorService));
if (editorService == null)
return null;
// This constructor should copy the buttons in its own list.
using (var form = new FooBar(b.CompactButtons)) {
if (editorService.ShowDialog(form) == DialogResult.OK && context.OnComponentChanging()) {
b.CompactButtons.Clear();
b.CompactButtons.AddRange(form.Buttons);
context.OnComponentChanged();
}
}
return value;
}
如果您的編輯器表單不是很專業,則可以嘗試CollectionEditor 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.