Рейтинг:
14
Richard Deeming
Элементы управления могут быть вложены в другие элементы управления; не все они являются прямыми дочерними элементами формы.
Вам понадобится рекурсивный метод для обработки всего дерева элементов управления:
private void btnFcolor_Click(object sender, EventArgs e)
{
using (var dlg = new ColorDialog())
{
if (dlg.ShowDialog() == DialogResult.OK)
{
SetLabelColor(Controls.Cast<Control>(), dlg.Color);
Properties.Settings.Default.FormForeColor = dlg.Color;
Properties.Settings.Default.Save();
}
}
}
private void SetLabelColor(IEnumerable<Control> controls, Color color)
{
foreach (Label label in controls.OfType<Label>())
{
label.ForColor = color;
}
foreach (Control control in controls.Where(c => c.HasChildren))
{
SetLabelColor(control.Controls.Cast<Control>(), color);
}
}
Smeezy
Спасибо, Ричард. Я попробовал ваш код, но получаю ошибки "волнистой линии". В частности, слова "где" и "контролирует" (с большой буквы С). Я не совсем понимаю все, что вы здесь сказали. Могу я где - нибудь почитать об этом? Нужно ли мне добавить "использование", ссылку или что-то еще?
Smeezy
Это у меня уже есть.
Richard Deeming
Ах, извините; я забыл, что коллекция элементов управления не сильно типизирована.
Вам понадобится ... .Cast<Control>()
до того, как .Where(...)
метод, чтобы заставить его работать.
foreach (Control control in controls.Cast<Control>().Where(c => c.HasChildren))
Richard Deeming
Или, если это выглядит немного пугающе, вы можете переместить условие внутри цикла:
foreach (Control control in controls)
{
if (control.HasChildren)
{
SetLabelColor(control.Controls, color);
}
}
Smeezy
Я попробую это сделать. У меня есть, чтобы перейти на что-то другое прямо сейчас. Я доложу, когда вернусь к этому. Спасибо.
Smeezy
Поэтому я продолжаю получать "элементы управления", подчеркнутые красным цветом, которые говорят: не удается преобразовать из "системы".Окна.Формы.Контроль.Система ControlCollection' to'.Окна.Форм.Форма.Экземпляре коллекции controlcollection в код кнопки.
Затем в методе SetLabelColor "Controls" и "Would" оба дают мне еще одно красное подчеркивание с ошибкой: "Form.ControlCollection" не содержит определения для "Controls" и не может быть найден доступный метод расширения "Controls", принимающий первый аргумент типа "Form.ControlCollection" (вы пропускаете директиву using или ссылку на сборку?)
Richard Deeming
Это раздражает - я не знаю, почему у них есть разные вложенные классы для представления коллекций элементов управления.
Попробуйте изменить SetLabelColor
способ принятия решения IEnumerable<Control>
, и добавление a .Cast<Control>()
к .Controls
коллекция, когда вы ее называете. Я обновил свой ответ с учетом изменений.
Smeezy
Привет, Ричард, я обновил информацию, как ты и просил, но все равно безуспешно. Как и раньше, метка ForeColor и кнопка Forecolor (чего я не хочу) меняются, но сохраняется только кнопка forecolor. Таким образом, кнопка forecolor меняется и сохраняется, как я и ожидал, просто это не должно происходить на кнопке! Но почему она меняется? Я не вижу ничего закодированного, чтобы это изменить. На этот раз я включил функции обратного цвета форм ниже, которые работают так, как они должны работать только в качестве ссылки.
//Возвращает FormBackColor к цвету установки по умолчанию. (это работает, как и ожидалось)
private void Form1_MouseClick(отправитель объекта, MouseEventArgs e)
{
этот.BackColor = Свойства.Настройки.По умолчанию.FormBackColor = Система.Рисование.Цвет.DarkSlateGray;
Свойства.Настройки.По умолчанию.Сохранить();
}
//Позволяет пользователю установить FormBackColor и сохранить его в качестве цвета по умолчанию. (это работает, как и ожидалось)
частная btnColor_Click недействительным(объект отправителя, EventArgs в электронной)
{
использование (var cd = new ColorDialog())
{
if (cd.ShowDialog() == DialogResult.ОК)
{
этот.BackColor = Свойства.Настройки.По умолчанию.FormBackColor = cd.Color;
Свойства.Настройки.По умолчанию.Сохранить();
}
}
}
//Создает элемент управления для изменения цвета метки forecolors. (при этом также изменяется кнопкой "цвет текста", хотя).
частный недействительными SetLabelColor(интерфейс IEnumerable&ЛТ;контроль&ГТ; управление, цвет)
{
foreach (Label label in controls.Метод oftype())
{
этикетка.Цвет текста = Цвет;
}
по каждому элементу (управление контроля в контроля.Где(c => c.HasChildren))
{
SetLabelColor(управление.Управления.Cast<control>(), цвет);
}
}
//Позволяет пользователю установить метку ForeColor и сохраняет ее в качестве цвета по умолчанию. (это позволит изменить метку и кнопку forecolors, но спасает только кнопка "цвет текста")
частная btnFcolor_Click недействительным(объект отправителя, EventArgs в электронной)
{
использование (var dlg = new ColorDialog())
{
if (dlg.ShowDialog() == DialogResult.ОК)
{
SetLabelColor(Элементы Управления.Cast<control>(), dlg.Цвет);
Свойства.Настройки.По умолчанию.FormForeColor = dlg.Цвет;
Свойства.Настройки.По умолчанию.Сохранить();
}
}
}
}
}
Richard Deeming
Это не имеет никакого смысла - .OfType<Label>()
будет только перебирать элементы управления, которые являются метками, а кнопки-не метками.
Вы уверены, что не используете LinkLabel
вместо а Button
?
Smeezy
Да. Я перетащил объекты кнопок из "общих элементов управления". Однако я думаю, что проблема заключается в "FormForeColor".
После выбора формы я создал объект привязки с именем
FormForeColor". В настройках приложения в свойствах я затем привязал это к формам "ForeColor". Я уверен, что это влияет на все объекты в форме, однако простое использование только "Forecolor" в элементе управления btnColor (ниже) дает мне еще одну ошибку подчеркивания.
частная btnFcolor_Click недействительным(объект отправителя, EventArgs в электронной)
{
использование (var dlg = new ColorDialog())
{
if (dlg.ShowDialog() == DialogResult.ОК)
{
SetLabelColor(Элементы Управления.Cast<control>(), dlg.Цвет);
Свойства.Настройки.По умолчанию.FormForeColor = dlg.Цвет;
Свойства.Настройки.По умолчанию.Сохранить();
}
}
Richard Deeming
Привязка является наиболее вероятным виновником - почти все элементы управления в форме наследуют свой forecolor от самой формы, если они не имеют явного набора значений.
Контроль.Свойства Forecolor (Системы.Окна.Формы) | Microsoft Docs[^]
"Этот ForeColor
свойство-это окружающее свойство. Окружающее свойство-это свойство элемента управления, которое, если оно не задано, извлекается из родительского элемента управления. Например, а Button
будет иметь то же самое BackColor
как его родитель Form
по умолчанию."
Вам нужно будет либо удалить привязку, либо установить определенную ForeColor
для элементов управления, которые вы не хотите менять.
NB: Если вы решите сохранить привязку, вам не нужно будет перебирать элементы управления, чтобы обновить их.
Smeezy
Я удалил привязку, и она действительно перестала влиять на цвет кнопки, но все равно не сохранит изменение.
Richard Deeming
Я не уверен, что понимаю. Вы получаете ошибку, или вы просто забыли позвонить в службу поддержки? SetLabelColor
метод, когда ваша форма загружается?
Smeezy
Я этого не устанавливал. Это так же просто, как поместить "SetLabelColor;" в Form1_Load?
Richard Deeming
Да, это должно сработать:
SetLabelColor(Controls.Cast<Control>(), Properties.Settings.Default.FormForeColor);
Smeezy
Не уверен, что я когда-нибудь выйду за рамки того, где я нахожусь с кодированием! Сейчас это вроде как работает. Независимо от того, какой цвет я выберу, когда я снова открою программу, передний цвет всех меток будет красным. Я не понимаю, откуда это берется.
//Позволяет пользователю установить метку ForeColor и сохраняет ее в качестве цвета по умолчанию.
частная btnFcolor_Click недействительным(объект отправителя, EventArgs в электронной)
{
использование (var dlg = new ColorDialog())
{
if (dlg.ShowDialog() == DialogResult.ОК)
{
SetLabelColor(Элементы Управления.Cast<control>(), dlg.Цвет);
}
}
частный недействительными SetLabelColor(интерфейс IEnumerable&ЛТ;контроль&ГТ; управление, цвет)
{
foreach (Label label in controls.Метод oftype())
{
этикетка.Цвет текста = Цвет;
}
по каждому элементу (управление контроля в контроля.Где(c => c.HasChildren))
{
SetLabelColor(управление.Управления.Cast<control>(), цвет);
}
}
частный недействительными методе form1_load(объект отправителя, EventArgs в электронной)
{
SetLabelColor(Элементы Управления.Cast<control>(), Свойства.Настройки.По умолчанию.FormForeColor);
}
Richard Deeming
Вы удалили код, который обновляет настройки.
private void btnFcolor_Click(object sender, EventArgs e)
{
using (var dlg = new ColorDialog())
{
if (dlg.ShowDialog() == DialogResult.OK)
{
SetLabelColor(Controls.Cast<Control>(), dlg.Color);
Properties.Settings.Default.FormForeColor = dlg.Color;
Properties.Settings.Default.Save();
}
}
}
Smeezy
ОК. Я только что это понял. Я забыл добавить диалог сохранения обратно!
Smeezy
Я очень ценю твою помощь Ричард! Это было поучительно, хотя бы для того, чтобы подкрепить знание о том, что мне предстоит пройти долгий путь! Однако мне нужно спросить, почему это было не так просто, как это было сделано с backcolor?
Richard Deeming
Если вы хотите изменить передний цвет всех элементов управления в форме, то должен сработать тот же подход привязки, который вы использовали для заднего цвета.
Это тот факт, что вы только хотели изменить цвет передней панели для определенного типа управления, что сделало его более сложным.
Smeezy
Понял. Еще раз спасибо!