VS .NET 自定义组件中的属性编辑样式为 DropDown

Property edit style as DropDown in a VS .NET custom component(VS .NET 自定义组件中的属性编辑样式为 DropDown)
本文介绍了VS .NET 自定义组件中的属性编辑样式为 DropDown的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在自定义控件/组件的属性窗口中使用 ComboBox 的功能作为 var 的编辑选项.不是 ComboBox 组件本身.

I'd like to use the functionality of a ComboBox as edit option for a var in the properties window of a custom control / component. Not the ComboBox component itself.

例如:

private string[] _stringArray = { "string0", "string1" };
public string[] StringArray
{
    get { return _stringArray; }
    //callback
    //set { _stringArray = value; }
}

如您所知,这将为我提供对象浏览器作为属性窗口中的查看/编辑选项.有趣的是,即使没有 setter,我也可以编辑值.

As you know this will give me the object browser as view/edit option in the property window. Funny thing that I can edit the values even with no setter.

在我的研究中,我发现这是可能的(UITypeEditorEditStyle.DropDown").但我不知道如何实现.或者我可以为StringArray"设置什么[指令].

In my researches I found out that it is possible ("UITypeEditorEditStyle.DropDown"). But I have no idea how to implement that. Or what [Instructions] I could set for the "StringArray".

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

My final goal is a copy of the object selector drop-down of visual studio as a property parameter:

当然是自定义事件处理.但正如你所见,我离实现这一点还很遥远.:(

我一直在寻找有关以下主题的教程:

With custom event handling of course. But as you see I'm far away to realize that. :(

I have been looking for a tutorial on the following topics for a long time:

  • [Designer] 说明参考
  • 管理属性显示样式的基础教程

但是我厌倦了我不成功的研究.一些好的链接总是受欢迎的.

However I'm tired of my unsuccessful researches. Some good links are always welcome.

推荐答案


更新:

在我或多或少地理解了原理之后(来自评论中的链接,谢谢),我找到了一个临时解决方案.我意识到我至少需要一个 int var 来设置选定的索引".我认为/希望 VS 可以自动执行此操作.就像枚举一样.我对[指令]缺乏了解.

我可以将字符串变量定义为数组的选定索引的占位符,以便在没有 TypeConverter 的情况下进行,但这更没有意义.我真的不需要另一个抽象变量.

所以基础下拉,例如可以直接显示枚举,貌似不适用.所以他们使用UITypeEditorEditStyle.DropDown"的技巧,这实际上不是下拉菜单.它只是一个按钮,您可以在其中放置您选择的控件.在我的例子中是一个 ListView.由于下降"的下降"已经存在.看起来像作弊.;)


UPDATE:

After I more or less understood the principle (from the link in the comments, thanks) I came to an interim solution. I realized that I need at least an int var to set a selected `index`. I thought / hoped that VS can do this automatically. Like it does with enums. And my lack of knowledge concerning [Instructions].

I could define a string variable as a placeholder for the selected index of the array in order to do without the TypeConverter, but that would make even less sense. I really don't need another abstract variable for nothing.

So the basis drop-down, which e.g. can display enums directly, does not appear to be applicable. So they use a trick with "UITypeEditorEditStyle.DropDown", which actually isn't a drop-down. It's just a button where you can place the control of your choice. In my case a ListView. Since the "drop" of the "down" already exists. Looks like cheating. ;)

//...
 
[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();
    }
}
 

实际上复制整个类只是为了更改SelectedIndex.正确的做法是滥用 SelectedIndex 并将其转换为字符串或类似的东西.我想我不再关心这个了.而是去呼吸新鲜空气.;)

Which actually copy the entire class just to change the SelectedIndex. The right thing would be to abuse the SelectedIndex and convert it to a string or something like that. I think I do not care about that anymore. Rather to catch some fresh air. ;)

也许这会对其他人有所帮助.

Maybe that will help someone else.

注意:这不是一个实际的建议.例如,如果您更改数组的(长度),则不会更新 SelectedIndex.我选择了 string[] 因为它是一个非常基本且众所周知的类型.我知道我的程序"没有实际用处.这只是关于理解原理.

Note: This is not a practical propose. As example SelectedIndex will not be updated if you change the (length) of the array. I've choosen string[] because it's a really basic and well known type. I am aware that my "program" has no real use. It was just about understanding the principle.

这篇关于VS .NET 自定义组件中的属性编辑样式为 DropDown的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)