在运行时切换UI资源

本文关键字:UI 资源 运行时 | 更新日期: 2023-09-27 18:19:06

我正在制作一个带有图标(图像)按钮的WinForms UI。目前,我只是在Visual Studio设计器中使用image属性为每个按钮分配图标图像。然而,我希望能够在运行时切换到不同的图标集/主题。我在stackoverflow上看到的答案的各种方法仅针对运行时,即代码加载各自的资源集,然后为每个按钮加载各自的图像资源并将其分配给按钮。有没有一种自动的方法来做这件事?基本上,我想避免对加载每个资源并将其分配给特定按钮的部分进行编码。

在运行时切换UI资源

您可以使用多个ImageList s来包含不同的主题图像,然后使用这些图像列表作为不同主题按钮的图像源。

  • 为每个主题创建ImageList
  • 设置每个ImageListTag属性为主题名称。(您不能在运行时通过名称访问组件,组件的name属性仅用于设计时,因此设置Tag属性以通过标记访问它们)
  • 设置ColorDepth属性为32位png图像和24位图图像
  • 设置图像的名称,并在不同的图像列表中使用相同的图像名称,例如在所有图像列表中添加按钮的图像使用"添加"名称。
  • 设置按钮的ImageList属性,并在设计时设置ImageIndexImageKey属性。使用ImageKey属性是首选的,因为如果在ImageList中没有键,它不会显示按钮的图像。
  • 在运行时更改ImageList属性以获得不同的按钮图像。

例如,您可以使用以下代码在运行时更改所有按钮的ImageList:

private IEnumerable<Control> GetAllControls(Control control)
{
    var controls = control.Controls.Cast<Control>();
    return controls.SelectMany(ctrl => GetAllControls(ctrl)).Concat(controls);
}
private void ChangeTheme(string themeName)
{
    GetAllControls(this).OfType<Button>().ToList()
        .ForEach(btn =>
        {
            btn.ImageList = this.components.Components
                                .OfType<ImageList>()
                                .Where(x => Convert.ToString(x.Tag).ToLower() == themeName.ToLower())
                                .FirstOrDefault();
        });
}

用法如下:

this.ChangeTheme("theme1");

并将所有按钮的图像列表设置为具有Tag属性的ImageList,其值为theme1