Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.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# 属性编辑样式作为VS.NET自定义组件中的下拉列表_C#_Visual Studio 2010_User Controls_Designer_Design Time - Fatal编程技术网

C# 属性编辑样式作为VS.NET自定义组件中的下拉列表

C# 属性编辑样式作为VS.NET自定义组件中的下拉列表,c#,visual-studio-2010,user-controls,designer,design-time,C#,Visual Studio 2010,User Controls,Designer,Design Time,我想在自定义控件/组件的属性窗口中将组合框的功能用作变量的编辑选项。而不是组合框组件本身 例如: private string[] _stringArray = { "string0", "string1" }; public string[] StringArray { get { return _stringArray; } //callback //set { _stringArray = value; } } 如您所知,这

我想在自定义控件/组件的属性窗口中将组合框的功能用作变量的编辑选项。而不是组合框组件本身

例如:

private string[] _stringArray = { "string0", "string1" };
public string[] StringArray
{
    get { return _stringArray; }
    //callback
    //set { _stringArray = value; }
}
如您所知,这将在属性窗口中为我提供“对象浏览器作为视图/编辑”选项。 有趣的是,即使没有setter,我也可以编辑这些值

在我的研究中,我发现这是可能的(“UITypeEditorEditStyle.DropDown”)。但我不知道如何实现这一点。 或者我可以为“StringArray”设置什么[说明]

我的最终目标是复制visual studio的“对象选择器”下拉列表作为属性参数:

当然是自定义事件处理。但正如你所见,我远远没有意识到这一点(

长期以来,我一直在寻找关于以下主题的教程:

  • [Designer]说明参考
  • 如何管理特性的显示样式的基本教程✔
然而,我厌倦了我不成功的研究。一些好的链接总是受欢迎的。


更新:

在我或多或少地理解了这个原则(从评论中的链接,谢谢)之后,我找到了一个临时解决方案。 我意识到我至少需要一个int-var来设置一个选定的“索引”。我认为/希望VS可以自动完成这项工作。就像枚举一样。而且我对[指令]缺乏了解。

我可以定义一个字符串变量作为数组所选索引的占位符,这样就不需要TypeConverter了,但这就没有什么意义了。我真的不需要另一个抽象变量。

因此,可以直接显示枚举的基本下拉列表似乎不适用。因此,他们使用了“UITypeEditorEditStyle.DropDown”的技巧,实际上它不是下拉列表。它只是一个按钮,您可以在其中放置您选择的控件。在我的例子中是一个列表视图。因为“down”的“drop”已经存在。看起来像作弊一样。;)

/。。。
[TypeConverter(typeof(StringArrayConverter))]
公共接口IStringArray
{
int SelectedIndex{get;set;}
字符串[]字符串数组{get;set;}
}
公共类DropDownStringArray:IStringArray
{
私有字符串[]_stringArray={“string0”、“string1”、“string2”、“string3”、“string4”、“string5”、“string6”};
public int SelectedIndex{get;set;}
公共字符串[]字符串数组
{
获取{return\u stringArray;}
设置{u stringArray=value;}
}
}
私有dropdownstringaray _ddsa=新的dropdownstringaray();
[编辑器(typeof(StringArrayTypeEditor),typeof(UITypeEditor))]
公共dropdownstringray我的dropdownstringray
{
获取{return\u ddsa;}
设置{u ddsa=value;}
}
//...
公共类StringArrayConverter:TypeConverter
{
公共覆盖布尔CanConvertTo(ITypeDescriptorContext上下文,类型destinationType)
{
返回destinationType==typeof(字符串);
}
公共重写对象转换为(ITypeDescriptorContext上下文、CultureInfo区域性、对象值、类型destinationType)
{
if(destinationType==typeof(string))
{
var sa=作为IStringArray的值;
如果(sa!=null){返回sa.StringArray[sa.SelectedIndex];}
}
返回“(无)”;
}
}
公共类StringArrayTypeEditor:UITypeEditor
{
私有iWindows FormsEditor服务(U editorService);
公共重写UITypeEditorEditStyle GetEditStyle(ITTypeDescriptorContext上下文){return UITypeEditorEditStyle.DropDown;}
公共重写对象EditValue(ITypeDescriptorContext上下文、IServiceProvider提供程序、对象值)
{
_editorService=(iIndowsFormsEditorService)provider.GetService(typeof(iIndowsFormsEditorService));
DROPDOWNSTRINGRAY ddsa=(DROPDOWNSTRINGRAY)值;
ListBox lb=新的ListBox();
lb.SelectionMode=SelectionMode.One;
对于(inti=0;i

它实际上是复制整个类来更改
SelectedIndex
。正确的做法是滥用SelectedIndex并将其转换为字符串或类似的内容。我想我不再在乎这个了。宁愿呼吸新鲜空气

也许这会帮助其他人


注:这不是一个切实可行的建议。例如,如果更改数组的(长度),SelectedIndex将不会更新。我之所以选择string[],是因为它是一种非常基本且众所周知的类型。我知道我的“程序”没有实际用途。这只是为了理解原理。

您可以从这里的几十个详细答案中开始;MSDN/MS文档中还有一些教程和权威文章。字符串数组是一个奇怪的选择,但如果它在枚举中不是“可设置的”,则类型转换器将在这种情况下工作。字符串[]只是组合框行的默认类型,这就是为什么我选择该类型作为示例…组合框对Items集合使用ObjectCollection-您可以在其中存储几乎任何内容,而不是字符串数组。它不仅仅是你所追求的“展示风格”。有些人将使用自定义UITypeEditor,但这仅适用于设计时的属性窗格。有些人会使用
TypeConverter
StandardValues
功能,该功能为用户界面提供一个道具窗格列表。关于这方面的详细信息在这里和微软文档中也有很多。明白了。也许我的问题是“溢出”的
//...
 
[TypeConverter(typeof(StringArrayConverter))]
public interface IStringArray
{
    int SelectedIndex { get; set; }
    string[] StringArray { get; set; }
}

public class DropDownStringArray : IStringArray
{
    private string[] _stringArray = { "string0", "string1", "string2", "string3", "string4", "string5", "string6" };
    public int SelectedIndex { get; set; }
    public string[] StringArray
    {
        get { return _stringArray; }
        set { _stringArray = value; }
    }
}

private DropDownStringArray _ddsa = new DropDownStringArray();
[Editor(typeof(StringArrayTypeEditor), typeof(UITypeEditor))]
public DropDownStringArray MyDropDownStringArray
{
    get { return _ddsa; }
    set { _ddsa = value; }
}
 
//...
 
public class StringArrayConverter : TypeConverter
{
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string))
        {
            var sa = value as IStringArray;
            if (sa != null) { return sa.StringArray[sa.SelectedIndex]; }
        }
        return "(none)";
    }
}

public class StringArrayTypeEditor : UITypeEditor
{
    private IWindowsFormsEditorService _editorService;

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.DropDown; }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        _editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
        DropDownStringArray ddsa = (DropDownStringArray)value;
        ListBox lb = new ListBox();
        lb.SelectionMode = SelectionMode.One;
        for (int i = 0; i < ddsa.StringArray.Length; i++) { lb.Items.Add(ddsa.StringArray[i]); }
        lb.SetSelected(ddsa.SelectedIndex, true);
        lb.SelectedValueChanged += OnListBoxSelectedValueChanged;
        _editorService.DropDownControl(lb);
        if (lb.SelectedItem != null) { ddsa.SelectedIndex = lb.SelectedIndex; }
        return value;
    }

    private void OnListBoxSelectedValueChanged(object sender, EventArgs e)
    {
        _editorService.CloseDropDown();
    }
}