【问题标题】:How to create a property to store the index of the selected value from another property?如何创建一个属性来存储来自另一个属性的选定值的索引?
【发布时间】:2009-06-12 09:01:17
【问题描述】:

我需要帮助解决以下问题:

我有一个有两个属性的类。

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?

【问题讨论】:

    标签: c# properties propertygrid


    【解决方案1】:

    您需要将自定义 TypeConverter 附加到 SelectedValue 属性,并使 PossibleValues 不可浏览。 TypeConverter 将负责在 PropertyGrid 中显示字符串而不是整数。所以基本上,你需要重写 CanConvertFrom、CanConvertTo、ConvertFrom 和 ConvertTo。当您想要获取自定义字符串时,请使用传递给这些方法的上下文参数并在您的目标实例中调用您的 PossibleValues 属性。那应该可以。看来您在这里不需要任何自定义 UITypeEditor。

    【讨论】:

    • 我认为 GetStandardValuesSupported 和 GetStandardValues 用于在属性编辑器中显示组合框。不幸的是,GetStandardValues 必须返回一个包含与属性本身相同类型的元素的集合,至少根据 msdn.microsoft.com/en-us/library/ayybcxe5.aspx 。如何使属性编辑器显示带有 ConvertFrom 或 ConvertTo 方法的组合框?
    • 是的,GetStandardValues 将返回您的本机类型(字节)。这就是触发组合框的原因。 ConvertFrom 和 ConvertTo 将简单地与您的自定义字符串进行转换,以便字符串而不是字节将显示在列表中。
    【解决方案2】:

    为什么不在字典类型中将它们绑定在一起,而不是两个单独的属性。在这种情况下使用起来容易得多。以您的索引作为键,将字符串 [] 作为值。只是不要将自己限制为索引的一个字节。

    【讨论】:

    • 如果我将 PossibleValues 从 string[] 更改为 Dictionary 我仍然需要一个属性来存储当前选择的值。应用程序处理来自外部设备的信息,并在处理完信息后发回。我使用字节数据类型,因为这个设备只接受从 0 到 255 的值。
    猜你喜欢
    • 1970-01-01
    • 2013-07-15
    • 1970-01-01
    • 2017-09-07
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    相关资源
    最近更新 更多