C#自定义属性如何显示下拉框?

VictorCheng6296 2017-04-25 09:56:53
namespace DataBaseType
{
public partial class Form1 : Form
{
public static string filename = null;
private String Databasetype = "MySql";
[TypeConverter(typeof(DataBaseTypeConverter)), CategoryAttribute("数据库")]
public String DataBaseType
{
get { return Databasetype; }
set { Databasetype = value; }
}
public class DataBaseTypeConverter : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}

public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(new string[] { "MySql", "Oracle", "ODBC" }); //为啥添加到属性里就不显示下拉框,而缺省是显示的
}

public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return false;
}
}

public Button Button
{
get { return Button1; }
set { Button1 = value; }
}

public Form1()
{
InitializeComponent();

CustomPropertyCollection bt = new CustomPropertyCollection();
bt.Add(new CustomProperty("数据库类型","DataBaseType","数据库类型","数据库类型。",this));//不显示下拉框
//bt.Add(new CustomProperty("数据库类型", "DataBaseType", "数据库", "数据库类型。", this, typeof(CustomDataBaseTypeEditor)));//该如何处理
bt.Add(new CustomProperty("标题", "Text", "数据", "要显示的内容。", Button1));
bt.Add(new CustomProperty("背景色", "BackColor", "外观", "背景色。", Button1));
bt.Add(new CustomProperty("颜色", "ForeColor", "外观", "前景色。", Button1));
propertyGrid1.SelectedObject = bt;
}
private void Button2_Click(object sender, EventArgs e)
{
propertyGrid1.SelectedObject = this; //这里是显示下拉框的
}
}

#region CustomProperty
class CustomDataBaseTypeEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override Object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (edSvc != null)
{
ComboBox cb = new ComboBox();
cb.Items.Add("MySql");
cb.Items.Add("Oracle");
cb.Items.Add("ODBC");
//如何弹出窗口让用户选择呢?
return cb.SelectedValue;
}
return value;
}
}

public class CustomProperty
{
#region Private Variables
private string _name = string.Empty;
private object _defaultValue = null;
private object _value = null;
private object _objectSource = null;
private PropertyInfo[] _propertyInfos = null;
#endregion
#region Contructors
public CustomProperty()
{
}
public CustomProperty(string name, string category, string description, object objectSource)
: this(name, name, null, category, description, objectSource, null)
{
}
public CustomProperty(string name, string propertyName, string category, string description, object objectSource)
: this(name, propertyName, null, category, description, objectSource, null)
{
}
public CustomProperty(string name, string propertyName, string category, string description, object objectSource, Type editorType)
: this(name, propertyName, null, category, description, objectSource, editorType)
{
}
public CustomProperty(string name, string propertyName, Type valueType, string category, string description,
object objectSource, Type editorType)
: this(name, new string[] { propertyName }, valueType, null, null, false, true, category, description, objectSource, editorType)
{
}
public CustomProperty(string name, string[] propertyNames, string category, string description, object objectSource)
: this(name, propertyNames, category, description, objectSource, null)
{
}
public CustomProperty(string name, string[] propertyNames, string category, string description, object objectSource, Type editorType)
: this(name, propertyNames, null, category, description, objectSource, editorType)
{
}
public CustomProperty(string name, string[] propertyNames, Type valueType, string category, string description,
object objectSource, Type editorType)
: this(name, propertyNames, valueType, null, null, false, true, category, description, objectSource, editorType)
{
}
public CustomProperty(string name, string[] propertyNames, Type valueType, object defaultValue, object value,
bool isReadOnly, bool isBrowsable, string category, string description, object objectSource, Type editorType)
{
Name = name;
PropertyNames = propertyNames;
ValueType = valueType;
_defaultValue = defaultValue;
_value = value;
IsReadOnly = isReadOnly;
IsBrowsable = isBrowsable;
Category = category;
Description = description;
ObjectSource = objectSource;
EditorType = editorType;
}
#endregion
#region Public Properties
public string Name
{
get { return _name; }
set
{
_name = value;

if (PropertyNames == null)
{
PropertyNames = new string[] { _name };
}
}
}
public string[] PropertyNames { get; set; }
public Type ValueType { get; set; }
public object DefaultValue
{
get { return _defaultValue; }
set
{
_defaultValue = value;
if (_defaultValue != null)
{
if (_value == null) _value = _defaultValue;
if (ValueType == null) ValueType = _defaultValue.GetType();
}
}
}
public object Value
{
get { return _value; }
set
{
_value = value;

OnValueChanged();
}
}
public bool IsReadOnly { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public bool IsBrowsable { get; set; }
public object ObjectSource
{
get { return _objectSource; }
set
{
_objectSource = value;
OnObjectSourceChanged();
}
}
public Type EditorType { get; set; }
#endregion
#region Protected Functions
protected void OnObjectSourceChanged()
{
if (PropertyInfos.Length == 0) return;

object value = PropertyInfos[0].GetValue(_objectSource, null);
if (_defaultValue == null) DefaultValue = value;
_value = value;
}
protected void OnValueChanged()
{
if (_objectSource == null) return;

foreach (PropertyInfo propertyInfo in PropertyInfos)
{
propertyInfo.SetValue(_objectSource, _value, null);
}
}
protected PropertyInfo[] PropertyInfos
{
get
{
if (_propertyInfos == null)
{
Type type = ObjectSource.GetType();
_propertyInfos = new PropertyInfo[PropertyNames.Length];
for (int i = 0; i < PropertyNames.Length; i++)
{
_propertyInfos[i] = type.GetProperty(PropertyNames[i]);
}
}
return _propertyInfos;
}
}
#endregion
#region Prublic Functions
public void ResetValue()
{
Value = DefaultValue;
}
#endregion
}
}
...全文
717 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
VictorCheng6296 2017-04-26
  • 打赏
  • 举报
回复
引用 4 楼 stherix 的回复:
另外 如果只是下拉框选择一个字符串的话 是不需要UIEditor的 只要继承StringConverter并且在ProperDescriptor的实现里override Converter并返回这个Converter就可以
我的需求是只需要一个下拉框选择字符串,但不知道如何override converter public class DataBaseTypeConverter : StringConverter { public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { return new StandardValuesCollection(new string[] { "MySql", "Oracle", "ODBC" }); } public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return false; } } public class CustomPropertyDescriptor : PropertyDescriptor { private CustomProperty _customProperty = null; public override TypeConverter Converter { get { //return base.Converter; //缺省的语句 return (TypeConverter)Test.Form1.DataBaseTypeConverter;//这里该如何写呢,这样会出错的,提示给定的上下文无效 } } }
VictorCheng6296 2017-04-26
  • 打赏
  • 举报
回复
引用 3 楼 stherix 的回复:
不要用ComboBox用个ListBox之类的代替,当ItemClick的时候关闭listbox 或者自己写一个form
一、使用ListBox界面显示很完美,但如何在ItemClick时关闭listbox呢。 if (edSvc != null) { ListBox lb = new ListBox(); lb.Items.Add("MySql"); lb.Items.Add("Oracle"); lb.Items.Add("OleDB"); lb.Click += lb_Click; edSvc.DropDownControl(lb); value = lb.SelectedItem; } void lb_Click(object sender, EventArgs e) { //这里该如何写呢 //((ListBox)sender).Parent.ControlRemoved(sender); ((ListBox)sender).Parent.Visible = false;//这种方法不行,第二次点击后下拉框不出来了 // ((ListBox)sender).Visible = false;//也不行,外框还在 } 二、使用Form,在Form上放一个Listbox,在ItemChanged事件中关闭Form, 在设置断点时可以关闭,可断点去掉后就关闭不了。 private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { result = this.listBox1.SelectedItem.ToString();//在这里设置断点可以关闭,但去掉断点就关闭不了。 this.Close(); }
VictorCheng6296 2017-04-26
  • 打赏
  • 举报
回复
终于解决了,感谢stherix
stherix 2017-04-26
  • 打赏
  • 举报
回复
要关闭下拉的ListBox 应该 edSvc.CloseDropDown();
stherix 2017-04-26
  • 打赏
  • 举报
回复
return Test.Form1.DataBaseTypeConverter;//这里该如何写呢,这样会出错的,提示给定的上下文无效 改成 return new Test.Form1.DataBaseTypeConverter(); 试试
VictorCheng6296 2017-04-25
  • 打赏
  • 举报
回复
自动的属性就可以显示: 添加到属性集里反而不显示:
stherix 2017-04-25
  • 打赏
  • 举报
回复
另外 如果只是下拉框选择一个字符串的话 是不需要UIEditor的 只要继承StringConverter并且在ProperDescriptor的实现里override Converter并返回这个Converter就可以
stherix 2017-04-25
  • 打赏
  • 举报
回复
不要用ComboBox用个ListBox之类的代替,当ItemClick的时候关闭listbox 或者自己写一个form
VictorCheng6296 2017-04-25
  • 打赏
  • 举报
回复
增加了个customdatabasetypeeditor ,下拉框能显示出来,但原来的编辑框如何去掉呢 class customdatabasetypeeditor : UITypeEditor { public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context) { return UITypeEditorEditStyle.DropDown; } public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value) { IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); if (edSvc != null) { ComboBox cb = new ComboBox(); cb.Items.Add("MySql"); cb.Items.Add("Oracle"); cb.Items.Add("OleDB"); edSvc.DropDownControl(cb);//如何将原来缺省的编辑框替换 value = cb.SelectedItem; } return base.EditValue(context, provider, value); } }  

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧