#c# #winforms
#c# #winforms
Вопрос:
Я пытаюсь создать пользовательскую панель, где я могу изменять свойства, используя Свойства -> Кнопки -> [(Коллекция) …]:
Следующее, что я пробовал
public class CustomPanel : Panel
{
private List<Button> buttons = new List<Button>();
public List<Button> Buttons
{
get { return buttons; }
set
{
buttons = value;
this.Controls.Clear();
foreach (var button in buttons)
{
button.Size = new Size(200, 30);
this.Controls.Add(button);
}
}
}
}
Но когда я добавляю новую кнопку с помощью Properties -> Buttons -> [(Collection) …]: она не добавляет ее на мою панель.
Комментарии:
1. Вы также должны каким-то образом указать местоположение!
2. Обратите внимание, что параметр свойства будет срабатывать только при назначении ему объекта списка, а не при добавлении элементов в этот список. Я не совсем уверен, что вы имеете в виду
Properties -> Items -> [(Collection) ...]
.3. @TaW я могу это сделать, но в любом случае это не войдет в мой список
4. Ваш код работает не так, как ожидалось, потому
List<>
что это коллекция сама по себе, аPanel.Controls
это совершенно другая коллекция!! Вам необходимо синхронизировать их в обоих направлениях каждый раз, когда один из них изменяется, ноList<>
не допускает такого поведения. Возможно, изменениеList<Button>
наButton[]
может разрешить или помочь. Вам следует переосмыслить цели такого подхода: вам нужна коллекцияButton
элементов управления только потому, что вы хотите отфильтровать любой другой видControl
, или… вы хотитеButton
, чтобы на панель добавлялись только элементы управления?5. @TaW обратите внимание, что проблема, вероятно, возникает в окне свойств конструктора, который вы не можете отлаживать, если не запустите второй экземпляр среды разработки (Visual Studio ?) и Не присоедините его отладчик к экземпляру, в котором запущен конструктор. Альтернативой реальному отладчику может быть ведение журнала / отображение сообщений (MessageBox . Показать, консоль. WriteLine или пользовательская альтернатива) путем добавления явных инструкций по всему коду для отладки.
Ответ №1:
Предполагая CustomPanel
, что класс был добавлен в качестве пользовательского элемента управления, а его базовый класс изменен на Panel
, вы можете попробовать следующий код.
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Linq;
using System.Windows.Forms;
namespace TEST
{
public partial class CustomPanel : Panel
{
public CustomPanel()
{
InitializeComponent();
}
[Editor(typeof(ArrayEditor), typeof(UITypeEditor))]
public Button[] Buttons
{
get { return this.Controls.OfType<Button>().ToArray(); }
set
{
SuspendLayout();
try
{
this.Controls.Clear();
foreach (var button in value)
{
button.Size = new Size(200, 30);
this.Controls.Add(button);
}
}
finally { ResumeLayout(); }
}
}
}
}
Убедитесь, что в проекте есть ссылка на System.Design.dll
, для ArrayEditor
распознавания.
Имейте в виду, что:
- Каждый
Button
элемент управления, добавленный дизайнером черезButtons
свойство, будет сериализован, как он был добавлен обычным способом проектирования. - Добавление других (не
Button
) элементов управления по-прежнему возможно обычным способом проектирования или программно. this.Controls.Clear
удалит любой элемент управления, даже те, которые добавлены без использованияButtons
; вы можете удалить эту инструкцию, если хотите сохранить их, но вам понадобится способ распознать ранее существующие кнопки и заменить или сохранить их по мере необходимости.- Все свойства любого
Button
объекта можно редактировать внутриArrayEditor
формы. - Вам необходимо обработать позиционирование элементов
Button
управления (как недавно добавленных, так и существующих), чтобы избежать дублирования.
Я предлагаю использовать дочерний FlowLayoutPanel
элемент для автоматического позиционирования кнопок и для предотвращения непосредственного доступа к коллекции кнопок. При таком подходе this.Controls
станет flowLayoutPanel1.Controls
(или похожим). В противном случае вы должны переопределить OnControlAdded
и OnControlRemoved
получать уведомления, когда какой-либо элемент управления добавляется или удаляется.