加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – Visual Studio“选择资源”对话框替换

发布时间:2020-12-15 21:47:38 所属栏目:百科 来源:网络整理
导读:在我的项目中,我有超过750个图像资源.使用VS内置的“选择资源”对话框是一个噩梦,可以找到并选择一个图像 – 比方说 – 用于 winforms设计器中的按钮. 如果它是一些像对话框这样的浏览器并且缺乏搜索功能,它将更有用. 你知道如何更换这个对话框吗? 有没有可
在我的项目中,我有超过750个图像资源.使用VS内置的“选择资源”对话框是一个噩梦,可以找到并选择一个图像 – 比方说 – 用于 winforms设计器中的按钮.

如果它是一些像对话框这样的浏览器并且缺乏搜索功能,它将更有用.

>你知道如何更换这个对话框吗?
>有没有可以做到的扩展?
>如果没有这样的扩展,我会创建一个扩展/加载项,无论我需要做什么.如果可以完成,你有任何实际经验吗?
>我以为我会找到合适的dll并扩展它的beaviour,但不幸的是我找不到哪个dll包含这个悲剧

任何帮助将不胜感激,谢谢!

解决方法

“资源选择”对话框是UITypeEditor.它是内部类ResourceEditorSwitch< T>它在内部使用内部类ResourcePickerDialog,它们都在Microsoft.VisualStudio. Windows.Forms.dll程序集中,它是Visual Studio程序集之一.

由于该类的实现与Visual Studio程序集的其他内部类紧密耦合,因此很难提取类源代码并对其进行自定义,但是您拥有有关该类的信息将有助于我们查看其源代码代码,让我们获得有关该类的更多信息.

要自定义“资源选择”对话框,您可以在设计时获取该类的实例,并在显示对话框之前,使用代码操作对话框以获得如下gif的过滤功能,注意我添加到的对话框.对话:

enter image description here

您可以通过键入TextBox并使用↑和↓键来过滤ListBox,而无需从TextBox更改焦点,您可以选择过滤结果.

为此,您应该:

>创建一个ControlDesigner并将其注册为控件的设计者.然后在其OnCreateHandle中找到您要编辑的属性.例如BackgroundImage.
>找到该属性的UITypeEditor.编辑器是ResourceEditorSwitch< T>的类型.它使用ResourcePickerDialog的一个实例.获取ResourcePickerDialog的实例.
>获取resourcePickerUI字段并创建ResourcePickerUI对话框的实例.这是您应该更改的对话框.该对话框包含一些TableLayoutPanel.您应该在适当的位置插入TextBox并处理其TextChanged事件并过滤ListBox中显示的值.所有控件都有名称,您只需访问它们并更改其属性和值即可.
>更改表单后,为其指定resourcePickerUI.这样,编辑器将使用更改的表单并显示您需要的内容.

履行

您可以在以下存储库中找到完整的工作示例:

> r-aghaei/CustomizeSelectResourceDialog
> Download zip

以下是设计师的代码:

public class MyControlDesigner : ControlDesigner
{
    protected override void OnCreateHandle()
    {
        base.OnCreateHandle();
        var property = TypeDescriptor.GetProperties(this.Control)["BackgroundImage"];
        var resourceEditorSwitch = property.GetEditor(typeof(UITypeEditor)) as UITypeEditor;
        var editorToUseField = resourceEditorSwitch.GetType().GetProperty("EditorToUse",BindingFlags.NonPublic | BindingFlags.Instance);
        var editorToUse = editorToUseField.GetValue(resourceEditorSwitch);
        var resourcePickerUIField = editorToUse.GetType().GetField("resourcePickerUI",System.Reflection.BindingFlags.Instance |
            System.Reflection.BindingFlags.NonPublic);
        var resourcePickerUI = (Form)Activator.CreateInstance(resourcePickerUIField.FieldType);
        ModifyForm(resourcePickerUI);
        resourcePickerUIField.SetValue(editorToUse,resourcePickerUI);
    }
    void ModifyForm(Form f)
    {
        var resourceContextTableLayoutPanel = GetControl<TableLayoutPanel>(f,"resourceContextTableLayoutPanel");
        var resourceList = GetControl<ListBox>(f,"resourceList");
        resourceContextTableLayoutPanel.Controls.Remove(resourceList);
        var tableLayoutPanel = new TableLayoutPanel();
        tableLayoutPanel.Dock = DockStyle.Fill;
        tableLayoutPanel.Margin = new Padding(0);
        tableLayoutPanel.ColumnCount = 1;
        tableLayoutPanel.RowCount = 2;
        tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
        tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent,100));

        List<string> list = new List<string>();
        var textBox = new TextBox() { Dock = DockStyle.Fill,Margin = resourceList.Margin };
        Action<string> applyFilter = (s) =>
        {
            if (string.IsNullOrEmpty(s))
            {
                resourceList.BeginUpdate();
                resourceList.Items.Clear();
                resourceList.Items.AddRange(list.ToArray());
                resourceList.EndUpdate();
            }
            else
            {
                var list2 = list.Where(x => x.ToLower().StartsWith(s.ToLower())).ToList();
                resourceList.BeginUpdate();
                resourceList.Items.Clear();
                resourceList.Items.Add("(none)");
                resourceList.Items.AddRange(list2.ToArray());
                resourceList.EndUpdate();
            }
            if (resourceList.Items.Count > 1)
                resourceList.SelectedIndex = 1;
            else
                resourceList.SelectedIndex = 0;
        };
        var resxCombo = GetControl<ComboBox>(f,"resxCombo");
        resxCombo.SelectedValueChanged += (s,e) =>
        {
            resxCombo.BeginInvoke(new Action(() =>
            {
                if (resourceList.Items.Count > 0)
                {
                    list = resourceList.Items.Cast<string>().ToList();
                    textBox.Text = string.Empty;
                }
            }));
        };
        textBox.TextChanged += (s,e) => applyFilter(textBox.Text);
        textBox.KeyDown += (s,e) =>
        {
            if (e.KeyCode == Keys.Up)
            {
                e.Handled = true;
                if (resourceList.SelectedIndex >= 1)
                    resourceList.SelectedIndex--;
            }
            if (e.KeyCode == Keys.Down)
            {
                e.Handled = true;
                if (resourceList.SelectedIndex < resourceList.Items.Count - 1)
                    resourceList.SelectedIndex++;
            }
        };
        tableLayoutPanel.Controls.Add(textBox,0);

        resourceList.EnabledChanged += (s,e) =>
        {
            textBox.Enabled = resourceList.Enabled;

        };
        tableLayoutPanel.Controls.Add(resourceList,1);
        resourceContextTableLayoutPanel.Controls.Add(tableLayoutPanel,4);
    }
    T GetControl<T>(Control c,string name)
        where T : Control
    {
        return (T)c.Controls.Find(name,true).FirstOrDefault();
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读