2016-03-04 13 views
1

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

У меня есть , где одна кнопка создает новый . Этот элемент управления пользователя имеет 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, я решил после того, как много читал о том, что «лучшая практика», чтобы создать и разрушить элементы управления, как вы нуждаются в них, особенно если у вас их много на форме. Если я полностью вне базы/безумный на этом, пожалуйста, дайте мне знать, чтобы я мог сделать легкий выход :)

ответ

0

Похоже, что ваш TodayCallHistory создает свой собственный Form1 и слушает событие на этом объекте.

Необходимо передать фактический Form1, который имеет пользовательский элемент управления, а затем зарегистрировать обработчик событий на этом объекте.

Что-то вроде этого:

В TodayCallHistory.cs:

public void SetParentForm(Form1 parent) 
{ 
    frm = parent; 
    frm.SaveClick += new EventHandler(saveWasClicked); 
} 

Form1.cs В:

public Form1 
{ 
    InitializeComponent(); 
    this.myTodayCallHistory.SetParentForm(this); 
} 

вопрос вытекает из следующего:

public partial class TodayCallHistory : UserControl 
{ 
    private Form1 frm = new Form1(); 

Созданный здесь Form1 - это совершенно другой объект, кроме «оригинального», кнопка сохранения которого вы нажимаете. Вместо создания совершенно нового объекта вам нужно каким-то образом передать оригинал. Метод SetParentForm() - это всего лишь один из способов сделать это.

+0

Я получаю следующее сообщение об ошибке «this.tch.SetParentForm (this);» part ... 'Form1' не содержит определения для 'tch', и не может быть найден метод расширения 'tch', принимающий первый аргумент типа 'Form1' (вам не хватает директивы использования или ссылки на сборку?) Я обновил свой код выше, чтобы также показать мое создание UserControl, поскольку оно не существует до нажатия кнопки. Возможно, это проблема? – koosh

+0

Я понял это с вашей помощью - СПАСИБО СМОТРЕТЬ! Мне просто нужно было переместить часть SetParentForm после создания UserControl. Серьезно, это сводило меня с ума от того, почему он не работает, и я не могу поблагодарить вас за то, что вы дали мне прямой, понятный и подробный ответ. Теперь я буду исследовать, как работают родительские формы. – koosh

+0

@koosh «Родительская форма» не является реальной концепцией. Проблема в вашем случае состоит в том, что вы создали два разных экземпляра 'Form1': первый содержит экземпляр вашей' TodayCallHistory', который, как его конструктор, создает новый экземпляр 'Form1' под названием' frm'. Объект с именем 'frm' является тем же _type_, но не тем же самым объектом. Метод 'SetParentForm()', который я предложил, - это просто способ дать 'TodayCallHistory' ссылку на' Form1'. Я уточню ответ, чтобы сделать это более понятным. –