如何解决VS .NET自定义组件中的属性编辑样式为DropDown
我想使用ComboBox的功能作为自定义控件/组件的属性窗口中var的编辑选项。不是ComboBox组件本身。
例如:
private string[] _stringArray = { "string0","string1" };
public string[] StringArray
{
get { return _stringArray; }
//callback
//set { _stringArray = value; }
}
如您所知,这将在属性窗口中为我提供对象浏览器的查看/编辑选项。 有趣的是,即使没有设置器,我也可以编辑值。
在我的研究中,我发现这是可能的(“ UITypeEditorEditStyle.DropDown”)。但是我不知道如何实现。 或者我可以为“ StringArray”设置什么[说明]。
我的最终目标是将Visual Studio的对象选择器下拉列表作为属性参数复制:
当然具有自定义事件处理功能。但是正如您所看到的,我距离实现这一目标还很遥远。 :(
很长时间以来,我一直在寻找有关以下主题的教程:
- [Designer]说明参考
-
有关如何管理属性的显示样式的基本教程✔
但是,我对自己的研究失败感到厌倦。总是欢迎一些好的链接。
解决方法
更新:
在我或多或少地理解了原理之后(通过评论中的链接,谢谢),我得出了一个临时解决方案。 我意识到我至少需要一个int var来设置选定的`index`。我认为/希望VS可以自动执行此操作。就像枚举一样。而且我缺乏关于[说明]的知识。
我可以将字符串变量定义为数组的选定索引的占位符,以便在没有TypeConverter的情况下执行此操作,但这将毫无意义。我真的不需要其他抽象变量。
因此基础下拉列表,例如可以直接显示枚举,似乎不适用。因此,他们通过“ UITypeEditorEditStyle.DropDown”使用了一个技巧,它实际上并不是一个下拉菜单。这只是一个按钮,您可以在其中放置您选择的控件。就我而言,是一个ListView。由于“下降”的“下降”已经存在。看起来像作弊。 ;)
//...
[TypeConverter(typeof(StringArrayConverter))]
public interface IStringArray
{
int SelectedIndex { get; set; }
string[] StringArray { get; set; }
}
public class DropDownStringArray : IStringArray
{
private string[] _stringArray = { "string0","string1","string2","string3","string4","string5","string6" };
public int SelectedIndex { get; set; }
public string[] StringArray
{
get { return _stringArray; }
set { _stringArray = value; }
}
}
private DropDownStringArray _ddsa = new DropDownStringArray();
[Editor(typeof(StringArrayTypeEditor),typeof(UITypeEditor))]
public DropDownStringArray MyDropDownStringArray
{
get { return _ddsa; }
set { _ddsa = value; }
}
//...
public class StringArrayConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context,Type destinationType)
{
return destinationType == typeof(string);
}
public override object ConvertTo(ITypeDescriptorContext context,CultureInfo culture,object value,Type destinationType)
{
if (destinationType == typeof(string))
{
var sa = value as IStringArray;
if (sa != null) { return sa.StringArray[sa.SelectedIndex]; }
}
return "(none)";
}
}
public class StringArrayTypeEditor : UITypeEditor
{
private IWindowsFormsEditorService _editorService;
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.DropDown; }
public override object EditValue(ITypeDescriptorContext context,IServiceProvider provider,object value)
{
_editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
DropDownStringArray ddsa = (DropDownStringArray)value;
ListBox lb = new ListBox();
lb.SelectionMode = SelectionMode.One;
for (int i = 0; i < ddsa.StringArray.Length; i++) { lb.Items.Add(ddsa.StringArray[i]); }
lb.SetSelected(ddsa.SelectedIndex,true);
lb.SelectedValueChanged += OnListBoxSelectedValueChanged;
_editorService.DropDownControl(lb);
if (lb.SelectedItem != null) { ddsa.SelectedIndex = lb.SelectedIndex; }
return value;
}
private void OnListBoxSelectedValueChanged(object sender,EventArgs e)
{
_editorService.CloseDropDown();
}
}
实际上只是复制整个类以更改SelectedIndex
。正确的做法是滥用SelectedIndex并将其转换为字符串或类似的东西。我想我已经不在乎了。而是要呼吸一些新鲜空气。 ;)
也许会帮助别人。
注意:这不是实际的建议。例如,如果更改数组的(长度),则SelectedIndex将不会更新。我选择了string [],因为它是一种非常基本且众所周知的类型。我知道我的“程序”没有实际用途。只是要了解原理。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。