Изменить значок Winform по умолчанию во всем приложении

Могу ли я изменить значок по умолчанию, используемый в Winform?

В большинстве моих форм для свойства значка установлено значение пользовательского значка. Для нескольких форм, которые ускользают, мне не нужна общая иконка «Эй, смотрите, он сделал это в визуальной студии».

Одним из решений является утомительная проверка каждой из моих форм, чтобы убедиться, что у них либо есть собственный набор значков, либо для параметра ShowIcon установлено значение False.

Другое решение состоит в том, чтобы каждая из моих форм наследовала от базового класса, который устанавливает пользовательский значок в конструкторе.

Помимо этих решений, какие еще у меня есть варианты?

РЕДАКТИРОВАТЬ: я надеялся, что будет способ заменить источник стоковой иконки моим собственным. Это где-то в файле ресурсов? Или он встроен в .NET dll, который я не могу (или действительно не должен) изменять?

РЕДАКТИРОВАНИЕ BOUNTY: Есть ли способ сделать это без редактирования или написания единой строки кода? Меня не волнует, насколько непрактичным, сложным, пустой тратой времени является решение... Я просто хочу знать, возможно ли это. Мне нужно удовлетворить свое любопытство.


person Kyle Gagnet    schedule 05.08.2009    source источник


Ответы (5)


Значок по умолчанию встроен в dll winforms. Глядя на рефлектор (DefaultIcon), он выглядит следующим образом:

defaultIcon = new Icon(typeof(Form), "wfc.ico");

Там нет магии, которая проверяет другое общее местоположение, поэтому вы не можете сделать это без изменения кода.

Вы всегда можете принять силы тьмы с помощью полевого отражения? Примечание: это хакерский и хрупкий. На свою голову! Но это работает:

[STAThread]
static void Main() {
    // pure evil
    typeof(Form).GetField("defaultIcon",
            BindingFlags.NonPublic | BindingFlags.Static)
        .SetValue(null, SystemIcons.Shield);

    // all forms now default to a shield
    using (Form form = new Form()) {
        Application.Run(form);
    }
}

Делать это правильно; два распространенных варианта;

  • базовый класс Form, у которого есть набор значков
  • метод factory Form - возможно, что-то вроде:

код:

public static T CreateForm<T>() where T : Form, new() {
    T frm = new T();
    frm.Icon = ...
    // any other common code
    return frm;
}

Тогда вместо:

using(var frm = new MySpecificForm()) {
    // common init code
}

Что-то типа:

using(var frm = Utils.CreateForm<MySpecificForm>()) {

}

Конечно - это не намного красивее! Другим вариантом может быть метод расширения С# 3.0, возможно, в виде свободного API:

public static T CommonInit<T>(this T form) where T : Form {
    if(form != null) {
        form.Icon = ...
        //etc
    }
    return form;
}

а также

using(var frm = new MySpecificForm().CommonInit()) {
    // ready to use
}

Тогда это всего лишь .CommonInit() от вашего существующего кода.

person Marc Gravell    schedule 02.10.2009
comment
Принято за фактическое обнаружение значка... достаточно близко - person Kyle Gagnet; 02.10.2009
comment
Опция отражения отлично сработала, и с API-интерфейсом отражения платформы O2 код для этого не выглядит таким страшным typeof(Form).fieldValue(defaultIcon, SystemIcons.Shield); - person Dinis Cruz; 08.01.2012

Опция базового класса — это та, которую мы используем.

Если вы ищете альтернативу (не обязательно хорошую), вы можете: 1. Использовать IOC для создания экземпляров всех ваших форм и изменить контейнер IOC для установки значка приложения. 2. Используйте АОП для вставки кода во все формы, который устанавливает значок приложения.

Лично я бы просто использовал базовый класс...

person ConsultUtah    schedule 05.08.2009

Мой полезный ответ:

No

Было бы неплохо реализовать Microsoft, поскольку большинство приложений используют один и тот же значок во всем приложении.

person Jage    schedule 01.10.2009

Если вы хотите обновить все значки другим, вы можете создать небольшое приложение, которое редактирует все файлы *.Designer.vb (в vb.net) и добавляет следующую строку в InitializeComponent:

Me.Icon = New System.Drawing.Icon("C:\PathTo\icon.ico")

Надеюсь, поможет.

person Sebastian    schedule 07.08.2009

Если все ваши формы находятся только в одном проекте, вы можете взять dll проекта и использовать отражение, чтобы получить каждый тип в dll. Если тип является производным от Form, вы можете установить свойство Icon типа на все, что хотите. Я не уверен, каковы будут накладные расходы на производительность, если проект очень большой.

person IordanTanev    schedule 05.08.2009