Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建一个属性来存储另一个属性中选定值的索引?_C#_Properties_Propertygrid - Fatal编程技术网

C# 如何创建一个属性来存储另一个属性中选定值的索引?

C# 如何创建一个属性来存储另一个属性中选定值的索引?,c#,properties,propertygrid,C#,Properties,Propertygrid,我需要以下问题的帮助: 我有一个具有两个属性的类 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_possibleVa

我需要以下问题的帮助:

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

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包含实际选定值的索引

在此状态下,属性编辑器将显示选定值的索引。我想使用属性网格中的组合框选择值,与枚举属性使用的样式相同。组合框的列表将从PossibleValues属性填充

在本文()的帮助下,我成功地创建了一个自定义编辑器,该编辑器在属性网格上显示combobox,其中包含来自PossibleValues属性的值。我也可以选择值,但属性网格仍然显示值的索引,而不是值本身

这是编辑器的修改源(源代码来自CodeProject):

公共类EnumParamValuesEditor:UITypeEditor
{
私人iWindows FormsEditor服务edSvc;
公共重写UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext上下文)
{
if((context!=null)&&(context.Instance!=null))
返回UITypeEditorEditStyle.DropDown;
返回UITypeEditorEditStyle.None;
}
公共重写对象EditValue(System.ComponentModel.ITypeDescriptorContext上下文,IServiceProvider提供程序,对象值)
{
if((context==null)| |(provider==null)| |(context.Instance==null))
返回base.EditValue(提供程序,值);
edSvc=(IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
如果(edSvc==null)
返回base.EditValue(提供程序,值);
ListBox lst=新的ListBox();
PrepareListBox(lst,上下文);
lst.SelectedIndex=(字节)值;
edSvc.下拉控制(lst);
如果(lst.SelectedItem==null)
值=空;
其他的
值=(字节)lst.SelectedIndex;
返回值;
}
私有void PrepareListBox(ListBox lst,ITypeDescriptorContext上下文)
{
lst.IntegralHeight=真;
字符串[]coll=((EnumTerminalParam)context.Instance);
如果(lst.ItemHeight>0)
{
如果((coll!=null)&&(lst.Height/lst.ItemHeight200)
adjHei=200;
第一高度=调整高度;
}
}
其他的
地面高度=200;
lst.Sorted=true;
FillListBoxFromCollection(lst,coll);
lst.SelectedIndexChanged+=新事件处理程序(lst\u SelectedIndexChanged);
}
void lst\u SelectedIndexChanged(对象发送方,事件参数e)
{
如果(edSvc==null)
返回;
edSvc.CloseDropDown();
}
公共作废FillListBoxFromCollection(列表框lb、ICollection coll)
{
lb.开始更新();
lb.Items.Clear();
foreach(coll中的对象项)
lb.项目。添加(项目);
lb.EndUpdate();
lb.使无效();
}
}
当然,它需要进一步修改以正确处理某些情况(例如,可能的值为空)


那么,是否可以在属性编辑器中显示可能的值[SelectedValue]而不是SelectedValue?

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

您需要将自定义类型转换器附加到SelectedValue属性,并使可能的值不可浏览。TypeConverter将负责显示PropertyGrid中的字符串,而不是int。所以基本上,您需要覆盖CanConvertFrom、CanConvertTo、ConvertFrom和ConvertTo。如果要获取自定义字符串,请使用传递给这些方法的上下文参数,并在目标实例中调用PossibleValues属性。这应该可以了。这里似乎不需要任何自定义UITypeEditor。

如果我将可能的值从string[]更改为Dictionary,我仍然需要一个属性来存储当前选定的值。应用程序处理来自外部设备的信息,并在处理后将信息发回。我使用字节数据类型是因为此设备只接受0到255之间的值。我认为GetStandardValuesSupported和GetStandardValues用于在属性编辑器中显示组合框。不幸的是,GetStandardValues必须返回一个集合,其中包含与属性本身相同类型的元素,至少根据。如何使属性编辑器显示包含ConvertFrom或ConvertTo方法的组合框?是的,GetStandardValues将返回本机类型(字节)。这将触发一个组合框。ConvertFrom和ConvertTo只需对自定义字符串进行转换,就可以在列表中显示字符串而不是字节。
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();
    }

}