Я пытался понять это в течение большей части двух дней и искал везде, чтобы найти решение, поэтому, если это легко ответить, я извиняюсь перед началом. Кроме того, я довольно новичок в C# и программировании в целом.Динамически созданная кнопка обнаружения элемента управления пользователя нажатием основной формы
У меня есть form, где одна кнопка создает новый usercontrol. Этот элемент управления пользователя имеет listview (пока, в какой-то момент, я, вероятно, собираюсь изменить это на datagridview), который обновляется информацией из базы данных Access. Когда нажата другая кнопка (Сохранить) в форме, информация добавляется в базу данных. Я бы хотел, чтобы мой UserControl обнаружил, когда нажата кнопка «Сохранить» и обновляется список.
Ниже приведен образец из моего кода, подвешенный к тому, что я надеюсь, являются важными битами.
Форма вещи.
public partial class Form1 : Form
{
public event EventHandler saveClick;
public Form1()
{
InitializeComponent();
}
public void buttonSave_Click(object sender, EventArgs e)
{
//Stuff happens here that saves all input to the database
if (this.saveClick != null)
this.saveClick(this, e);
}
//Creates the UserControl TodayCallHistory as tch and expands Form1 window to accomodate the new control
private void butListShow_Click(object sender, EventArgs e)
{
if (!expanded)
{
expanded = true;
butListShow.Text = "\u25C0";
TodayCallHistory tch = new TodayCallHistory();
tch.Name = "tch";
tch.SetParentForm(this); //This was added per the answer below
List<int> pos = new List<int>();
foreach (Control x in this.Controls)
{
int right = x.Right;
pos.Add(right);
}
tch.Location = new System.Drawing.Point(pos.Max() + 10, 10);
formWidth = this.Width;
this.Width = this.Width + tch.Width + 10;
this.Controls.Add(tch);
}
else
{
expanded = false;
butListShow.Text = "\u25B6";
foreach (Control x in this.Controls)
{
if (x.Name == "tch")
this.Controls.Remove(x);
}
this.Width = formWidth;
}
}
}
UserControl stuff.
public partial class TodayCallHistory : UserControl
{
private Form1 frm = new Form1();
public TodayCallHistory()
{
InitializeComponent();
//frm.saveClick += new EventHandler(saveWasClicked); Removed based on answer below
}
//This following part was added per the marked answer below
public void SetParentForm(Form1 parent)
{
frm = parent;
frm.saveClick += new EventHandler(saveWasClicked);
}
private void saveWasClicked(object sender, EventArgs e)
{
refreshList();
}
private void refreshList()
{
//Sends query to database and then populates a listview with this information
}
}
Когда кнопка «Сохранить» нажата на форме, в UserControl ничего не происходит. Просто большая куча ничего. Если кто-нибудь скажет мне, что я делаю неправильно или лучший способ приблизиться к этому, я был бы чрезвычайно благодарен! Я также могу опубликовать больше своего кода, если я не буду делиться достаточно.
EDIT 1: Следует также упомянуть, что это WinForm, написанный в C# с использованием Visual Studio Express 2015 для Windows Desktop.
EDIT 2: Добавлен код для создания UserControl при нажатии кнопки Form1. Эта же кнопка также удаляет элемент управления. В основном я хотел иметь «окно расширения» (я понятия не имею, что такое фактический термин), как часть моего Form1.
EDIT 3: Используя предложение Harrison Paine (не уверен, как пометить имя пользователя) ниже, я добавил метод SetParentForm в UserControl. Поскольку мой UserControl не создается до тех пор, пока кнопка не нажмет на Form1, мне пришлось добавить SetParentForm в Form1 после его создания.
Сразу после
tch.Name = "tch";
Я добавил
tch.SetParentForm(this);
EDIT 4: Таким образом, чтобы избежать создания нового Form1, я сделал следующие изменения.
Form1
public static event EventHandler saveClick; //Added static modifier
public void buttonSave_Click(object sender, EventArgs e)
{
//Stuff happens here that saves all input to the database
if (Form1.saveClick != null)
Form1.saveClick(this, e); //Changed this.saveClick to Form1.saveClick
}
private void butListShow_Click(object sender, EventArgs e)
{
tch.Parent = this; //All the other stuff from above, plus this now
}
Я изменил this.saveClick
к Form1.saveClick
, так как это имеет статический модификатор (я в основном догадалась я должен был сделать это, и я до сих пор работает на понимании именно то, что «статический» делает ха)
UserControl
public TodayCallHistory()
{
Form1.saveClick += new EventHandler(saveWasClicked);
InitializeComponent();
}
я удалил Form1 frm = new Form1();
, а также весь SetParentForm
м енит.
Для тех, кому интересно, почему я не просто иметь UserControl созданы и всегда, только с .Visible
набором для True
или False
, я решил после того, как много читал о том, что «лучшая практика», чтобы создать и разрушить элементы управления, как вы нуждаются в них, особенно если у вас их много на форме. Если я полностью вне базы/безумный на этом, пожалуйста, дайте мне знать, чтобы я мог сделать легкий выход :)
Я получаю следующее сообщение об ошибке «this.tch.SetParentForm (this);» part ... 'Form1' не содержит определения для 'tch', и не может быть найден метод расширения 'tch', принимающий первый аргумент типа 'Form1' (вам не хватает директивы использования или ссылки на сборку?) Я обновил свой код выше, чтобы также показать мое создание UserControl, поскольку оно не существует до нажатия кнопки. Возможно, это проблема? – koosh
Я понял это с вашей помощью - СПАСИБО СМОТРЕТЬ! Мне просто нужно было переместить часть SetParentForm после создания UserControl. Серьезно, это сводило меня с ума от того, почему он не работает, и я не могу поблагодарить вас за то, что вы дали мне прямой, понятный и подробный ответ. Теперь я буду исследовать, как работают родительские формы. – koosh
@koosh «Родительская форма» не является реальной концепцией. Проблема в вашем случае состоит в том, что вы создали два разных экземпляра 'Form1': первый содержит экземпляр вашей' TodayCallHistory', который, как его конструктор, создает новый экземпляр 'Form1' под названием' frm'. Объект с именем 'frm' является тем же _type_, но не тем же самым объектом. Метод 'SetParentForm()', который я предложил, - это просто способ дать 'TodayCallHistory' ссылку на' Form1'. Я уточню ответ, чтобы сделать это более понятным. –