gpt4 book ai didi

c# - Visual Studio "Select Resource"对话框替换

转载 作者:行者123 更新时间:2023-11-30 12:48:09 25 4
gpt4 key购买 nike

在我的项目中,资源中有超过 750 张图片。使用内置在“选择资源”对话框中的 VS 来查找和选择一个图像(比方说)对于 winforms 设计器中的按钮来说是一场噩梦。

如果它是一些类似对话框的资源管理器并且缺少搜索功能,它会更有用。

  • 你知道如何替换这个对话框吗?

  • 有没有扩展可以做到这一点?

  • 如果没有这样的扩展,我会创建一个扩展/加载项,无论我需要做什么。如果完全可以做到,您有实际经验吗?

  • 我以为我会找到合适的dll并扩展它的行为,但不幸的是我找不到哪个dll包含这个悲剧

如有任何帮助,我们将不胜感激,谢谢!

最佳答案

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

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

要自定义资源选择对话框您可以在设计时获取该类的实例,并在显示对话框之前,使用代码操作对话框以具有如下 gif 的过滤功能,关注TextBox我已将其添加到对话框中:

enter image description here

您可以过滤 ListBox通过输入 TextBox并使用 键,而不从 TextBox 改变焦点您可以选择过滤后的结果。

为此,您应该:

  1. 创建 ControlDesigner并将其注册为您的控件的设计器。然后在其 OnCreateHandle找到您要编辑的属性。例如BackgroundImage .
  2. 找到 UITypeEditor该属性(property)的。编辑器类型为 ResourceEditorSwitch<T>它使用 ResourcePickerDialog 的实例.获取 ResourcePickerDialog 的实例.
  3. 获取 resourcePickerUI字段并创建 ResourcePickerUI 的实例对话。这是您应该更改的对话框。该对话框包含一些 TableLayoutPanel .您应该插入 TextBox在合适的地方处理它TextChanged事件并过滤 ListBox 中显示的值.所有控件都有名称,您可以简单地访问它们并更改它们的属性和值。

  4. 修改表格后赋值resourcePickerUI .这样,编辑器将使用更改后的表单并显示您需要的内容。

实现

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

这是设计器的代码:

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, 0);

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

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

关于c# - Visual Studio "Select Resource"对话框替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14952181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com