Перейти к содержимому

Фото
- - - - -

2 формы на C#. Передача данных с одной в другую.


  • Вы не можете создать новую тему
  • Please log in to reply
23 ответов в этой теме

#1 Sekret

Sekret
  • Новобранец
  • 11 сообщений

Отправлено 22 Февраль 2007 - 21:19

Имеется Форм1 и Форм3.
На Форм3 расположены Лэйблы с названиями продукции и к каждому лэйблу рядом текстбокс с ценой.
Количество названий продукции одно и то же, увеличиваться не будет, уменьшаться тоже.
Цены первоначальные имеются для каждого названия продукции. У тексбоксов свойству Enabled установлено false,
чтобы нельзя было изменить.

Выглядит это так:

рама1 450
рама2 580
рама3 875

и т.д.

На Форме3 также размещены две кнопки - <Изменить цену> и <сохранить изменения>.

Когда нажимаем на кнопку <Изменить цену>, то у текстбоксов свойство Enabled = true;
и можно вносить изменения. Затем нажимаем кнопку <сохранить изменения>.

Все расчёты проходят на Форме1. Значения цен с Формы3 поступает в Форму1.

Проблема в том, что я не знаю,как передать в Форму1 изменённые значения из Формы3,
т.к. передаются только те значения, которые находятся в конструкторе у Формы3(а в ней первоначальные значения).
Как изменённые значения внести в конструктор?
И если нет изменений, то будут браться первоначальные значения.

public partial class Form3 : Form
{
public int cena_rama1;
public int cena_rama2;



public Form3()
{
InitializeComponent();
cena_rama1 = 450;
cena_rama2 = 580;
}

private void Form3_Load(object sender, EventArgs e)
{
this.textBox1.Text = cena_rama1.ToString();

this.textBox2.Text = cena_rama2.ToString();
}

private void button1_Click(object sender, EventArgs e) // <Изменить цену>
{
textBox1.Enabled = true;
textBox2.Enabled = true;
}

private void button2_Click(object sender, EventArgs e) // <сохранить изменения>
{
try
{
cena_rama1 = int.Parse(textBox1.Text);
cena_rama2 = int.Parse(textBox2.Text);
}
catch
{
MessageBox.Show("!");

}

label3.Text = cena_rama1 + ", " + cena_rama2;

textBox1.Enabled = false;
textBox2.Enabled = false;
}
}


Хэлп!

:blink:
  • 0

#2 Warvick

Warvick
  • Пользователь
  • 411 сообщений
  • Откуда:Tallinn

Отправлено 22 Февраль 2007 - 21:50

public int cena_rama1;
public int cena_rama2;

они же public, плохо конечно, ну да уж ладно, как сделано так сделано.
public значит видны, используемым их классам. т.е. в форме1 можешь прямо к ним и обращаться :
SomeForm1Variable = MyForm3.cena_rama1; //(MyForm3 - экземпляр Form3

Только Forma1 должна иметь ссылку на Form3. Как это сделать зависит от приложения. Например так:
		private Form3 _myForm3;
		public Form3 MyForm3()
		{
			if (_myForm3 != null)			
				return _myForm3;			
			else 
				foreach (Form f in Application.OpenForms)				
					if (f is Form3) 
					{
						_myForm3 = (Form3)f;						
					}
			return _myForm3;
		}	  

Сообщение изменено: Warvick (22 Февраль 2007 - 22:00 )

  • 0
Да, я такой!

#3 Sekret

Sekret
  • Новобранец
  • 11 сообщений

Отправлено 22 Февраль 2007 - 21:54

public int cena_rama1;
public int cena_rama2;

они же public
т.е. в форме1 можешь прямо к ним и обращаться :
SomeForm1Variable = MyForm3.cena_rama1; //(MyForm3 - экземпляр Form3

Только Forma1 должна иметь ссылку на Form3.



Это я знаю.
Вот в Форме1 при нажатии на кнопку отображается цена:
public void button3_Click(object sender, EventArgs e)
{
Form3 form3 = new Form3();
form3.Show();
cena1 = form3.cena_rama1;
label23.Text = cena1.ToString();

}

НО! Отображается цена из конструктора Формы3, а в нём первоначальные данные. Изменения не фиксируются никак.
  • 0

#4 Warvick

Warvick
  • Пользователь
  • 411 сообщений
  • Откуда:Tallinn

Отправлено 22 Февраль 2007 - 22:07

Form3 form3 = new Form3();
form3.Show();
cena1 = form3.cena_rama1;

ты создаешь НОВЫЙ экземпляр формы
естессно там значения будут те, которые ты указал в конструкторе
а тебе надо взять занчения из СТАРОГО экземпляра формы3, см. мой правленный пост выше как это сделать.

т.е. применимо к моему коду.
NB! В момент нажатия на кнопку на форме1, форма3 должна быть ещё открыта!

public void button3_Click(object sender, EventArgs e)
{
cena1 = MyForm3.cena_rama1;
label23.Text = cena1.ToString();
}
  • 0
Да, я такой!

#5 Sekret

Sekret
  • Новобранец
  • 11 сообщений

Отправлено 22 Февраль 2007 - 22:28

Что-то мне тяжеловато. А куда в Форме1 это именно писать ?
private Form3 _myForm3;
public Form3 MyForm3()
{
if (_myForm3 != null)
return _myForm3;
else
foreach (Form f in Application.OpenForms)
if (f is Form3)
{
_myForm3 = (Form3)f;
}
return _myForm3;
}
Что значит is ? А можно с объяснениями подробными.. чтобы я смогла понять..?
Что нужно написать в Форм1 и Форм3?

Наверное, надо было сразу сказать, что Форм1 является главной, т.е. сначала она открывается. В ней ведутся все расчёты, берутся данные из Форм3(они берутся те, которые первоначально там). Кнопка на Форм1 для того, чтобы открыть Форм3 и может быть изменить там цены. Так вот если цены буду изменены и на Форме3 будет нажата кнопка внести изменения, тогда в Форме1 для расчётов должны браться уже изменённые цены. Вот в чём проблема.

Сообщение изменено: Sekret (22 Февраль 2007 - 22:49 )

  • 0

#6 Warvick

Warvick
  • Пользователь
  • 411 сообщений
  • Откуда:Tallinn

Отправлено 23 Февраль 2007 - 13:35

public partial class Form1 : Form
	{
	   



		public Form1()
		{
			InitializeComponent();
		}

#region Form3_handling
		private Form3 _form3; //reference to the active Form3 instance
		public Form3 MyForm3 //returns the instance of the Form3
		{
			get
			{
				if (_form3 == null) //tying to find open Form3
					foreach (Form f in Application.OpenForms)
						if (f is Form3)
						{
							_form3 = (f as Form3);
							break;
						}
				//else if  _form3 exists;
				if (_form3 == null)
					_form3 = new Form3();	
				return _form3;
			}
		}
 
#endregion Form3_handling		

		public void SetPrices()
		{ 
			tbCena1.Text  =MyForm3.Price1.ToString();
			tbCena2.Text = MyForm3.Price2.ToString();			
		}


		private void btnOpenForm3_Click(object sender, EventArgs e)
		{
			
			try
			{
				MyForm3.Show();
			}
			catch (ObjectDisposedException nex)
			{
				_form3 = new Form3();
				MyForm3.Show();
			}
		   
			MyForm3.OnPriceSaved += new Form3.PriceSavedHandler(this.SetPrices);

		}
	}

	public partial class Form3 : Form
	{
		private int _price1;
		private int _price2;
		public int Price1 { get {return _price1; } }
		public int Price2 { get { return _price2; } }

		public delegate void PriceSavedHandler(); //delegates
		public event PriceSavedHandler OnPriceSaved;
	   

		public Form3()
		{
			InitializeComponent();
			_price1 = 450;
			_price2 = 600;
			textBox1.Text = _price1.ToString();
			textBox2.Text = _price2.ToString();

		}

		private void button1_Click(object sender, EventArgs e)
		{
			_price1 = int.Parse(textBox1.Text);
			_price2 = int.Parse(textBox2.Text);
			if (OnPriceSaved != null)
				OnPriceSaved();

		}
	}

Разбирайся
tbCen1 i tbCena2 - текстбоксы на форме1
и учи delegates

Сообщение изменено: Warvick (23 Февраль 2007 - 13:36 )

  • 0
Да, я такой!

#7 Sekret

Sekret
  • Новобранец
  • 11 сообщений

Отправлено 23 Февраль 2007 - 15:35

спасибо большое. попробую.
  • 0

#8 Sekret

Sekret
  • Новобранец
  • 11 сообщений

Отправлено 23 Февраль 2007 - 17:39

Хмм.. сделала.. Но при повторном запуске приложения ведь цены остаются первоначальными.. не сохраняются изменения ведь.. :blink:
И ещё. Если изменить цену на любое двух или трёхзначное число, начинающееся с цифры 5( 52, 568), то отобразится число без этой 5 (2, 68). А если ввести 5, то ошибка вылетает.. Вот такие странности. У вас тоже так?

И вообще может это очень неправильно - хранить цены не в базе данных, а в текстбоксах??

А мне кажется неудобным хранить в базе это, т.к. тогда в базе будут 2 стобца(в первом - название, во втором - цена), и мне надо будет писать запрос столько раз, сколько у меня там элементов надо извлечь, т.к. каждому наименованию у меня должно быть своё имя, чтобы далее совершать операции.(умножать размеры на цены и т.д).

Можете чтоо посоветовать?

Простите, если гружу своими проблемами.. :(
  • 0

#9 Warvick

Warvick
  • Пользователь
  • 411 сообщений
  • Откуда:Tallinn

Отправлено 23 Февраль 2007 - 17:51

Sekret,
да уж.. все запущенно :)

с запятыми - это потому что используем тип int- целое число. Смените на double. Удостоверьтесть что у вас локальные настройки требуют "." а не "," в качестве разделителя разрядов. Или используй маски.

И вообще может это очень неправильно - хранить цены не в базе данных, а в текстбоксах??

:)) Конечно непраильно, если надо чтобы данные сохранялись между запусками программы. В исходном условии этого не было. Конечно БД надо использовать. Ну на худой конец сериализацию(храенниея состояния обьекта в XML файле).

А мне кажется неудобным хранить в базе это, т.к. тогда в базе будут 2 стобца(в первом - название, во втором - цена), и мне надо будет писать запрос столько раз, сколько у меня там элементов надо извлечь, т.к. каждому наименованию у меня должно быть своё имя, чтобы далее совершать операции.(умножать размеры на цены и т.д).

Вопрос сложный "как это должно выглядеть в базе". Зависит от целей и архитектуры приложения. Нужен dictionary типов товаров, или хотя бы просто товаров. В самом примитивном уровне - это то, как ты описала. Типа "Название Товара", "Цена". Дальше можно на форме датасет использовать который будет по ID или по имени товара находить нужную строчку... Но опять же, я не знаю какова конечная цель задачи, поэтому однозначно ответить нельзя.
  • 0
Да, я такой!

#10 Sekret

Sekret
  • Новобранец
  • 11 сообщений

Отправлено 23 Февраль 2007 - 17:59

нее, я не про дабл говорю.. я ввожу инт
В скобках просто привела примеры двух чисел.

ясно, значит надо с базой. Эх.. Мне стыдно за себя, но у меня куча вопросов.
Задача моя - сделать программу расчёта окон. А я её делаю как-то примитивно очень, не используя ни делегатов, ни всего остального.. Написала кода на 30 страниц.. всякие манипуляции с введёнными данными(формулы расчёта), теперь дошла до стоимости.. Мне надо перемножать, складывать и вычитать всякие показатели с ценой. Цена в принципе неизменна, но всё же должна быть возможность её менять..
  • 0

#11 Warvick

Warvick
  • Пользователь
  • 411 сообщений
  • Откуда:Tallinn

Отправлено 23 Февраль 2007 - 19:07

Sekret,
Хм.. странные глюки с 5кой, завтра проверю на работе :).

Стыдиться не надо, ничего страшного "Москва не сразу строилась" :), но вот учить придется очень много.
Если тебе нужно сохранять результаты расчетов то используй базу. Подойдет даже простенький Access.
Все расчеты лучше вынести в отдельный модуль/ класс(ы) в зависимости от сложности. Логику записи/вычитывания из базы тоже в отдельно.
Конкретезируй , что за вопросы воззникают.
  • 0
Да, я такой!

#12 Josso

Josso
  • Новобранец
  • 12 сообщений

Отправлено 04 Апрель 2007 - 15:28

Ещё вопрос..Такои же.
У меня на Форм1 идут рас4ёты. Там техтБохы и кнопка. В конструкторе первона4алйные зна4ения. Полйзователй может менятй их на любые другие. По нажатию кнопки из техтбохов берутся введённые данные для последующих рас4eтов.
На Форм2 мне надо взятj зна4ения из техтБохов Формы1.
Warvick, ты писал мне код и всё работало, но сеи4ас другои слу4аи. Мне не надо проверятй, открыта ли Форм1..она всегда открыта у меня. Попробовала убрала лишнее... и выдаёт error - Object reference not set to an instance of an object.

Еh..
  • 0

#13 Warvick

Warvick
  • Пользователь
  • 411 сообщений
  • Откуда:Tallinn

Отправлено 05 Апрель 2007 - 21:22

я как понимаю у тебя не MDi приложение...
ты при созданни формы 2 передать должна ссылку туда на главную форму (форму 1) -, или(топорный способ) пробегаться по всем открытым формам, и если найдена форма1 - брать оттуда значения.
вобщем код в студию :)
  • 0
Да, я такой!

#14 Josso

Josso
  • Новобранец
  • 12 сообщений

Отправлено 18 Апрель 2007 - 12:04

Не знаю, как тут из Мэйнформ передать значения текстбоксов в форму Клиент.

public partial class MainForm : Form // eto glavnaja forma. Vsegda otkryta.
{
private int _price1;
private int _price2;
public int Price1 { get {return _price1; } }
public int Price2 { get { return _price2; } }



public MainForm()
{
InitializeComponent();

textBox1.Text = "0"; // _price1
textBox2.Text = "0"; // _price2
}

private void btnCalculate_Click(object sender, EventArgs e) // Pods4joty
{
_price1 = int.Parse(textBox1.Text);
_price2 = int.Parse(textBox2.Text);
}


private void btnKlient_Click(object sender, EventArgs e) // otkrytie formy Klient
{
// zdesj mne nado, 4toby zna4enija iz textBox1 peredalisj v formu Klient


}
}



//-------------------------------------------------------------------------------------------------

public partial class Klient : Form
{
public Klient()
{
InitializeComponent();

label1.Text =MyMainForm.Price1.ToString(); // beru ceny iz MainForm
label2.Text = MyMainForm.Price2.ToString();
}

#region MainForm_handling
private MainForm _mainform; //reference to the active MainForm instance
public MainForm MyMainForm //returns the instance of the MainForm
{
get
{
if (_mainform == null) //tying to find open MainForm
foreach (Form f in Application.OpenForms)
if (f is MainForm)
{
_mainform = (f as MainForm);
break;
}
//else if _mainform exists;
if (_mainform != null)
_mainform = new MainForm();
return _mainform;
}
}

#endregion MainForm_handling


}
}
  • 0

#15 Josso

Josso
  • Новобранец
  • 12 сообщений

Отправлено 24 Апрель 2007 - 10:11

Help! Help! :(
  • 0

#16 Warvick

Warvick
  • Пользователь
  • 411 сообщений
  • Откуда:Tallinn

Отправлено 24 Апрель 2007 - 15:10


public Klient()

{

InitializeComponent();



label1.Text =MyMainForm.Price1.ToString(); // beru ceny iz MainForm

label2.Text = MyMainForm.Price2.ToString();

//------------------------------------------------------------------

textBoxXXX.Text = MyMainForm.someTextBox.Text

//------------------------------------------------------------------

}

  • 0
Да, я такой!

#17 Josso

Josso
  • Новобранец
  • 12 сообщений

Отправлено 24 Апрель 2007 - 15:43

Спасибо..попробую дома..
  • 0

#18 Josso

Josso
  • Новобранец
  • 12 сообщений

Отправлено 24 Апрель 2007 - 20:14

Передала так, как помог Варвик. Обратилась к текстбоксам главной формы. Работает.
  • 0

#19 Josso

Josso
  • Новобранец
  • 12 сообщений

Отправлено 30 Апрель 2007 - 09:05

A kak v Visual Studii vyrovnitj kod ? Ctrl+ ?


Ja uzhe nashla.. Ctrl+K, potom Ctrl+D

Сообщение изменено: Josso (30 Апрель 2007 - 09:35 )

  • 0

#20 zedirtybastard

zedirtybastard
  • Пользователь
  • 499 сообщений

Отправлено 04 Май 2007 - 16:12

У меня такой вопрос: кто-нить с NHibernate работал? Научите генерить маппинги в MyGeneration, задолбался уже с ними :)
  • 0

#21 ParadoxL

ParadoxL
  • Постоялец
  • 4 756 сообщений
  • Откуда:Edinburg

Отправлено 05 Май 2007 - 06:02

Извините конечно, но по моему скромному мнению ... изначально неправильно построена модель приложения.
  • 0
Victoria nulla est, Quam quae confessos animo quoque subjugat hostes ...
Верю в смерть после жизни, любовь после секса и в крем после бритья ...

#22 Josso

Josso
  • Новобранец
  • 12 сообщений

Отправлено 09 Май 2007 - 11:10

А вы не знаете, чем C# отличается от Visual C#? :rolleyes:
  • 0

#23 shb

shb

    New life, much more options

  • Постоялец
  • 5 253 сообщений
  • Откуда:Таллинн

Отправлено 15 Май 2007 - 08:19


Сообщение изменено: shb (15 Май 2007 - 08:20 )

  • 0
Мыслящий человек просто обязан время от времени поднимать себя за волосы © Тот самый Мюнгхаузен

Joga Bonito!

#24 ParadoxL

ParadoxL
  • Постоялец
  • 4 756 сообщений
  • Откуда:Edinburg

Отправлено 16 Май 2007 - 09:45

А вы не знаете, чем C# отличается от Visual C#? :rolleyes:

Visual C# ... это продукт из пакета Visual Studio от Microsoft... для разработки на C#.
А C# ... это сам язык.
  • 0
Victoria nulla est, Quam quae confessos animo quoque subjugat hostes ...
Верю в смерть после жизни, любовь после секса и в крем после бритья ...