2012-04-03 2 views
0

У меня есть 2 формы в настольном приложении C#. Form1 и Form2.Значение из Form2, не обновляющееся в Form2

Form1 содержит открытый метод, который добавляет элемент в контроле ListBox следующим образом:

public void AddToList(string item) 
{ 
    listBox.Items.Add(item); 
} 

Когда я называю этот метод непосредственно на некоторые нажатия кнопки, то он работает отлично. Но когда я вызываю этот метод из Form2, он ничего не добавляет в элементе управления ListBox в Form1. Код в форме 2 выглядит следующим образом:

Form1 frm = new Form1(); 
frm.AddToList("something"); 

Когда я запускаю это, ничего не происходит. Никакой ошибки нет. Он просто не добавляет ни одного элемента в ListBox.

Что я делаю неправильно?

+0

Похоже, вы создаете новый экземпляр Form1, а не ссылаетесь на существующий экземпляр в вашем графическом интерфейсе. Можете ли вы разместить больше своего кода на уровне GUI, где отображаются/используются Form1 и Form2? –

+0

У вас есть два * типа * в вашем проекте. Но вы создаете более одного * объекта * каждого типа. Добавьте frm.Show(), чтобы увидеть свою ошибку. –

+0

Как вы создаете свои две формы? Являются ли они оба созданы третьей формой, например MDI, или Form1, создающей Form2, или как? Это поможет нам дать ответ о том, как заставить ваши две формы разговаривать друг с другом. –

ответ

2

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

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

Мне не нравится этот подход с точки зрения дизайна.

Я бы предложил создать публичное событие в Form2, имея Form1 подписаться на это событие и добавить обработчик, который добавит элемент в список. Событие в Form2 будет выглядеть примерно так:

public event EventHandler ButtonClick 
{ 
    add 
    { 
     button1.Click += value; 
    } 
    remove 
    { 
     button1.Click += value; 
    } 
} 

Тогда вы будете иметь свойство, которое выглядит примерно так:

public string SomeValueForm1NeedsOnButtonClick 
{ 
    get 
    { 
     return texbox1.Text; 
    } 
} 

Тогда в Form1 вы будете иметь что-то вроде:

Form2 otherForm = new Form2(); 
otherForm.ButtonClick += (sender, args) => 
{ 
    listbox1.Items.Add(otherForm.SomeValueForm1NeedsOnButtonClick); 
}; 

Этот подход гарантирует, что каждая форма знает как можно меньше друг о друге. Это уменьшает сцепление между двумя классами и дает четкие представления будущим пользователям/читателям форм, что именно происходит между ними.

+0

Я получаю ошибку «Локальная переменная с именем« sender »не может быть объявлена ​​в этой области, потому что она будет давать другое значение ....« на этой строке »otherForm.ButtonClick + = (sender, args) =>« – Ali

+0

@ Али Просто назовите 'отправителя' что-то еще в одном из двух контекстов. Я не использовал его здесь, поэтому больше ничего не нужно обновлять. – Servy

+0

@Ali Имейте в виду, что это не значит, что это будет принято дословно, это высокий уровень, на что он должен выглядеть. Как минимум, большинство имен переменных должны быть изменены на то, что они фактически представляют. Эта общая схема - это то, что вы можете использовать для всех видов проблем с различными типами действий/событий. – Servy

0

Form1 frm = new Form1();

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

0

Хмм

Если вы следовали этот код с frm.Show() вы бы видели его. Необычный, что ты не хочешь.

Ваш подход к проблеме является чуть-чуть наивным.

Вы можете добавить свойство form2 и установить его в форму Form1, которую хотите использовать. (PS form1 и form2 не помогают, дают им имена. MainForm и DetailForm или somesuch).

Проблема с вышесказанным заключается в том, что вы внедрили ужасную зависимость.

Много способов пойти с этим, один из них будет отдельным классом для хранения списка (интерфейс и класс будут еще лучше). Затем добавьте свойство Form1 и Form2 типа или типа класса.

Form2 затем может добавлять вещи в список. Это вызывает событие с измененным списком. Form1 подключается к обработчику событий, а затем обновляет список, используемый для отображения действий.

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

Смежные вопросы