简体   繁体   English

如何创建一个属性来存储来自另一个属性的所选值的索引?

[英]How to create a property to store the index of the selected value from another property?

I need help with the following problem: 我需要以下问题的帮助:

I have a class with two properties. 我有一个有两个属性的类。

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; }
}

The PossibleValues stores the list of the selectable values. PossibleValues存储可选值的列表。 The SelectedValue contains the index of the actually selected value. SelectedValue包含实际选定值的索引。

In this state the property editor shows the index of the selected value. 在此状态下,属性编辑器显示所选值的索引。 I would like to select the value using a combobox in the property grid, the same style used with an Enum property. 我想在属性网格中使用组合框选择值,与Enum属性使用的样式相同。 The combobox's list would be populated from the PossibleValues property. 组合框的列表将从PossibleValues属性填充。

With the help of this article ( 在这篇文章的帮助下( http://www.codeproject.com/KB/cpp/UniversalDropdownEditor.aspx ) I have managed to create a custom editor that show the combobox on the property grid with the values from the PossibleValues property. http://www.codeproject.com/KB/cpp/UniversalDropdownEditor.aspx )我设法创建了一个自定义编辑器,它使用PossibleValues属性中的值显示属性网格上的组合框。 I can also select the value, but still the property grid shows the index of the value instead of the value itself. 我也可以选择值,但属性网格仍然显示值的索引而不是值本身。

This is the modified source of the editor (original is from CodeProject): 这是编辑器的修改源(原始来自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();
    }

}

Of course, it needs further modifications to correctly handle some situations (ex. the PossibleValues is empty). 当然,它需要进一步修改以正确处理某些情况(例如,PossibleValues为空)。

So is it possible to show the PossibleValues[SelectedValue] instead of the SelectedValue in the property editor? 那么可以在属性编辑器中显示PossibleValues [SelectedValue]而不是SelectedValue吗?

You need to attach a custom TypeConverter to your SelectedValue property and make the PossibleValues non browsable. 您需要将自定义TypeConverter附加到SelectedValue属性,并使PossibleValues不可浏览。 The TypeConverter will be responsible for showing strings in the PropertyGrid instead of ints. TypeConverter将负责在PropertyGrid中显示字符串而不是int。 So basically, you need to override CanConvertFrom, CanConvertTo, ConvertFrom and ConvertTo. 所以基本上,你需要覆盖CanConvertFrom,CanConvertTo,ConvertFrom和ConvertTo。 When you want to get your custom strings, use the context argument passed to these methods and call your PossibleValues property in your target instance. 如果要获取自定义字符串,请使用传递给这些方法的context参数,并在目标实例中调用PossibleValues属性。 That should make it. 那应该成功。 Seems you don't need any custom UITypeEditor here. 看来你这里不需要任何自定义UITypeEditor。

Instead of two separate properties why not tie them together within a Dictionary type. 而不是两个单独的属性,为什么不在Dictionary类型中将它们绑定在一起。 So much easier to use in this case. 在这种情况下使用起来更加容易。 With your index as the key and the string[] as values. 将索引作为键,将字符串[]作为值。 Just don't limit yourself to a byte for the index. 只是不要将自己限制为索引的一个字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM