Доступ публичного метода между формами
Я пытаюсь получить доступ к общедоступному методу Form1 в другой форме Form2, как показано ниже. у меня есть textbox6
контроль на form1 и есть публичный способ связать его. Но я хочу связать это с помощью form2, как показано ниже.
Form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
}
public void amount_sum()
{
string connstr = " server=.;initial catalog=maa;uid=mah;pwd=mah";
SqlConnection con = new SqlConnection(connstr);
con.Open();
string sql = " select sum(amount)as amount from method";
SqlDataAdapter dap = new SqlDataAdapter(sql, con);
DataSet ds = new DataSet();
dap.Fill(ds);
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
textBox6.Text = Convert.ToString(ds.Tables[0].Rows[i]["amount"]);
}
}
}
Form2
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
f1.amount_sum();
this.Close();
}
Вышеуказанный метод-вызов неверен. Подскажите пожалуйста как это исправить.
Я хочу связать Form1's textBox6
контроль от Form2's Button_Click
обработчик событий, вызывая открытый метод, и когда Form2 закрывается, тогда Form1 textbox6
должен быть связан. Это возможно, вызывая публичный метод из Form2?
4 ответа
В Form2 у вас есть
Form1 f1 = new Form1();
f1.amount_sum();
Кажется, это распространенная ошибка при создании новой формы Form1, когда вы хотите передать ответ обратно между формами. new
Ключевое слово делает это, он создает новую форму Form1, вызывает метод, не показывает форму, исходный экземпляр Form1 не затрагивается.
Я покажу несколько шагов, как это исправить.
1 - передать форму 1 в форму 2
Первое, что вы можете сделать, это просто передать существующую форму Form1 в форму Form2, чтобы Form2 знала, какую форму Form1 следует обновить.public class Form2
{
private readonly Form1 _form1;
public Form2(Form1 form1)
{
_form1 = form1;
}
private void button1_Click(object sender, EventArgs e)
{
_form1.amount_sum(); // now this updates the existing form1 instance
this.Close();
}
}
В форме 1
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(this); // pass this form1 instance to form2
f2.Show();
}
Одна из проблем заключается в том, что это создает сильную связь между Form1 и Form2. Если вы что-то измените в Form1, то легко сломать Form2 и наоборот.
2 - передать делегату
Вместо передачи всей формы Form1 в форму Form2 мы можем просто передать делегат методу обновления, который может запустить Form2. Это создает меньшую связь между Form1 и Form2, если вы вызываете Form2 из Form3, вы можете вместо этого передать метод обновления Form3, и Form3 будет обновлен. Одна и та же форма 2 может быть повторно использована без изменений.public class Form2
{
private readonly Action _ammountUpdater;
public Form2(Action ammountUpdater)
{
_ammountUpdater = ammountUpdater;
}
private void button1_Click(object sender, EventArgs e)
{
_ammountUpdater(); // now this updates the existing form1 instance
this.Close();
}
}
В форме 1
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(this.amount_sum); // pass the update method to form2
f2.Show();
}
Теперь вы можете изменить amount_sum
частным, так как теперь это действительно внутреннее дело Form1.
Я бы сделал твой amount_sum
method - служебный метод, который возвращает значение, например:
public static decimal GetTotalFoobarAmount()
{ // decimal is just a guess here
// omitted: sql code
return theAnswer;
}
Тогда оба блока кода могут вызывать этот метод, например.
textBox6.Text = YourClass.GetTotalFoobarAmount().ToString();
Как побочный эффект, он также уменьшает связь между вашим пользовательским интерфейсом и базой данных, что обычно считается хорошей вещью. Если для запроса в настоящее время требуются значения из формы, укажите эти параметры в методе. Обратите внимание, что для возврата одного значения вы можете посмотреть ExecuteScalar
; это не будет иметь большого значения, но это более прямое, чем заполнение DataTable
и цикл по одному ряду.
Также вы можете использовать события:
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ButtonClickAction += f2_ButtonClickAction;
f2.Show();
}
void f2_ButtonClickAction()
{
amount_sum();
}
Form2:
public Form2()
{
InitializeComponent();
}
public event Action ButtonClickAction;
private void button1_Click(object sender, EventArgs e)
{
Action a = ButtonClickAction;
if (a != null)
a();
this.Close();
}
Ответа Марка Гравелла, вероятно, достаточно, но в целом, если вы хотите вызвать метод экземпляра для определенного экземпляра класса, вы не можете просто создать новый и вызвать его в этом экземпляре. Для вашего примера вам нужно вызвать метод в экземпляре Form1, который уже существует. Лучший способ сделать это - иметь переменную-член класса Form2 типа Form1. Вы можете определить конструктор или свойство в Form2, которое принимает значение типа Form1 и задает в нем переменную-член. Когда Form1 создает экземпляр Form2, он может вызвать конструктор и передать this
или установите для свойства значение this
, Затем, когда кнопка нажата на Form2, вместо создания нового экземпляра Form1, она может вызвать amount_sum()
метод в экземпляре Form1, который уже сохранен.