[英]How to create a property to store the index of the selected value from another property?
我需要以下问题的帮助:
我有一个有两个属性的类。
private byte m_selectedValue;
public byte SelectedValue
{
get { return m_selectedValue; }
set { m_selectedValue = value; }
}
private string[] m_possibleValues;
public string[] PossibleValues
{
get { return m_possibleValues; }
set { m_possibleValues = value; }
}
PossibleValues存储可选值的列表。 SelectedValue包含实际选定值的索引。
在此状态下,属性编辑器显示所选值的索引。 我想在属性网格中使用组合框选择值,与Enum属性使用的样式相同。 组合框的列表将从PossibleValues属性填充。
在这篇文章的帮助下( http://www.codeproject.com/KB/cpp/UniversalDropdownEditor.aspx )我设法创建了一个自定义编辑器,它使用PossibleValues属性中的值显示属性网格上的组合框。 我也可以选择值,但属性网格仍然显示值的索引而不是值本身。
这是编辑器的修改源(原始来自CodeProject):
public class EnumParamValuesEditor : UITypeEditor
{
private IWindowsFormsEditorService edSvc;
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
if ((context != null) && (context.Instance != null))
return UITypeEditorEditStyle.DropDown;
return UITypeEditorEditStyle.None;
}
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if ((context == null) || (provider == null) || (context.Instance == null))
return base.EditValue(provider, value);
edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (edSvc == null)
return base.EditValue(provider, value);
ListBox lst = new ListBox();
PrepareListBox(lst, context);
lst.SelectedIndex = (byte)value;
edSvc.DropDownControl(lst);
if (lst.SelectedItem == null)
value = null;
else
value = (byte)lst.SelectedIndex;
return value;
}
private void PrepareListBox(ListBox lst, ITypeDescriptorContext context)
{
lst.IntegralHeight = true;
string[] coll = ((EnumTerminalParam)context.Instance).PossibleValues;
if (lst.ItemHeight > 0)
{
if ((coll != null) && (lst.Height / lst.ItemHeight < coll.Length))
{
int adjHei = coll.Length * lst.ItemHeight;
if (adjHei > 200)
adjHei = 200;
lst.Height = adjHei;
}
}
else
lst.Height = 200;
lst.Sorted = true;
FillListBoxFromCollection(lst, coll);
lst.SelectedIndexChanged += new EventHandler(lst_SelectedIndexChanged);
}
void lst_SelectedIndexChanged(object sender, EventArgs e)
{
if (edSvc == null)
return;
edSvc.CloseDropDown();
}
public void FillListBoxFromCollection(ListBox lb, ICollection coll)
{
lb.BeginUpdate();
lb.Items.Clear();
foreach (object item in coll)
lb.Items.Add(item);
lb.EndUpdate();
lb.Invalidate();
}
}
当然,它需要进一步修改以正确处理某些情况(例如,PossibleValues为空)。
那么可以在属性编辑器中显示PossibleValues [SelectedValue]而不是SelectedValue吗?
您需要将自定义TypeConverter附加到SelectedValue属性,并使PossibleValues不可浏览。 TypeConverter将负责在PropertyGrid中显示字符串而不是int。 所以基本上,你需要覆盖CanConvertFrom,CanConvertTo,ConvertFrom和ConvertTo。 如果要获取自定义字符串,请使用传递给这些方法的context参数,并在目标实例中调用PossibleValues属性。 那应该成功。 看来你这里不需要任何自定义UITypeEditor。
而不是两个单独的属性,为什么不在Dictionary类型中将它们绑定在一起。 在这种情况下使用起来更加容易。 将索引作为键,将字符串[]作为值。 只是不要将自己限制为索引的一个字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.