Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 6462
Последний выпуск: 19.06.2015

Взаимодействие в формочках

8.8K
07 мая 2011 года
Apach47
130 / / 14.06.2010
Здравствуйте.
Никак не могу сам дойти как реализовать следующую обработку действий юзера:
Имеются две формочки: Родитель(с гридом + датасоурс к гриду) и добавить(три текстбокса и две кнопки: Добавить и Отмена).
По кнопке, расположенной на "Родителе" открываю форму "Добавить" и далее... Нужно реализовать разные действия при клике на кнопках "Добавить" и "Отмена": при клике на первой создать объект, занести его в ArrayList и вывести в грид, на второй - просто закрыть форму.
В чем тут проблема, спросите Вы? Проблема в том, что обработку событий клика по кнопкам на форме "Добавить" нужно реализовать в классе-форме "Родитель", для чего моих знаний в С# пока явно не хватает.

Подскажите пожалуйста как это сделать.

Заранее благодарю
281
08 мая 2011 года
koodeer
1.2K / / 02.05.2009
Во-первых, необязательно обработку клика кнопки одной формы делать в другой форме. Можно просто сделать так: в первой форме ArrayList делаем public (или internal), а во вторую форму передаём ссылку на первую, и получаем доступ ко всем её публичным свойствам и полям.

Form1.cs:
 
Код:
public ArrayList arrayList = new ArrayList();

private void showButton_Click(object sender, System.EventArgs e)
{
    Form2 form2 = new Form2(this);
    form2.Show();
}


Form2.cs:
Код:
public Form2(Form1 form)
{
    InitializeComponent();
    form1 = form;
}

Form1 form1;

private void addButton_Click(object sender, EventArgs e)
{
    form1.arrayList.Add("value");
}


Всё делается без лишних инклюдов. C# настолько удобен в этом плане, что развращает и отучает напряжно думать :).



Если все же хочется клик по кнопке второй формы обрабатывать в первой форме, то можно примерно так:

Form1.cs:
Код:
public Form1()
{
    InitializeComponent();
    add = Form2_addButton_Click;
}

private ArrayList arrayList = new ArrayList();

public delegate void Add(object sender, EventArgs e);
public Add add;

void Form2_addButton_Click(object sender, EventArgs e)
{
    // ...
}

private void showButton_Click(object sender, EventArgs e)
{
    Form2 form2 = new Form2(this);
    form2.Show();
}


Form2.cs:
 
Код:
public Form2(Form1 form)
{
    InitializeComponent();
    form1 = form;
    addButton.Click += new EventHandler(form1.add);
}

Form1 form1;

То есть передаём во вторую форму делегат на метод в первой форме.
Делегат - это безопасный указатель. Сигнатура делегата должна совпадать с сигнатурой метода, на который он указывает.


PS: боюсь, hardcase или ещё кто-нибудь может нам надавать по шапке за то, что пытаемся работать из одной формы с членами другой напрямую, а не через класс-посредник.
8.8K
08 мая 2011 года
Apach47
130 / / 14.06.2010
koodeer, спасибо, сейчас попробую реализовать.
Кстати к ArrayList идет обращение аж через два контролирующих его согласованность класса)) Я просто задачу утрировал.
8.8K
08 мая 2011 года
Apach47
130 / / 14.06.2010
Цитата: koodeer

Form1.cs:
Код:
private ArrayList arrayList = new ArrayList();
//Так, тут понятно что делегат с сигнатурой метода
public delegate void Add(object sender, EventArgs e);
А это ссылка на вторую форму? (1)
public Add add;

public Form1()
{
    InitializeComponent();
//Событие Click по кнопке "Добавить" на второй форме? (2)
    add = Form2_addButton_Click;
}

void Form2_addButton_Click(object sender, EventArgs e)
{
//Т.е. событие по клику на кнопке, расположенной на второй форме обрабатываем здесь же(в первой форме)? (3)
    // ...
}

private void showButton_Click(object sender, EventArgs e)
{
//Ну тут все понятно
    Form2 form2 = new Form2(this);
    form2.Show();
}


Form2.cs:
 
Код:
public Form2(Form1 form)
{
    InitializeComponent();
    form1 = form;
//Немного не пойму почему именно form1.add. Поясните пожалуйста (4)
    addButton.Click += new EventHandler(form1.add);
}

Form1 form1;


Дайте пожалуйста комментарии насчет строк, помеченных цифрами в скобках

Цитата: koodeer
То есть передаём во вторую форму делегат на метод в первой форме.


Поправьте меня, если я не прав, но вы передаете из первой формы во вторую не делегат, а this(указатель на себя). Вызова делегата я не вижу.

281
08 мая 2011 года
koodeer
1.2K / / 02.05.2009
Цитата: Apach47
Дайте пожалуйста комментарии насчет строк, помеченных цифрами в скобках



Цитата:
А это ссылка на вторую форму? (1)
public Add add;


Это объявление переменной. Имя - add. Тип - Add.


Цитата:
//Событие Click по кнопке "Добавить" на второй форме? (2)
add = Form2_addButton_Click;


Здесь нашему делегату add присваивается непосредственная ссылка на метод.


Цитата:
//Т.е. событие по клику на кнопке, расположенной на второй форме обрабатываем здесь же(в первой форме)? (3)
// ...


Да. Этот метод первой формы будет вызываться во второй форме через делегат.


Цитата:
//Немного не пойму почему именно form1.add. Поясните пожалуйста (4)
addButton.Click += new EventHandler(form1.add);


form1.add - это наш делегат, указывающий на метод Form2_addButton_Click в первой форме. Таким образом событие клик этой кнопки будет вызывать этот метод.



Цитата: Apach47
Поправьте меня, если я не прав, но вы передаете из первой формы во вторую не делегат, а this(указатель на себя). Вызова делегата я не вижу.


Да, тут я неправльно выразился. Во вторую форму передаём указатель на первую форму, а во второй форме через этот указатель получаем доступ к делегатам первой формы.

8.8K
08 мая 2011 года
Apach47
130 / / 14.06.2010
Большое спасибо. С этим разобрался, но возникла другая проблема...

На второй форме было пару элементов управления из которых я получал введенные юзверем данные. Сделав их public и разместив в функции первой форме я перестал получать из них значения...
Првожу код
Код:
//Ссылка на главный менеджер(класс, управляющий поведением списка)
        private static GeneralManager _showProductGenManager;
        //Вызов обработчика кнопки "Добавить" из формы AddForm
        public delegate void Helpy(object sender, EventArgs e);
        //Инстанцируем делегат
        public Helpy AddAndEdit;


        public ShowProduct( GeneralManager gm )
        {
            InitializeComponent();
            _showProductGenManager = gm;
            AddAndEdit += FormAddProduct_AddsAndEdits_Click;
        }

        //Обработка события Click для кнопки Add на форме AddProduct
        private void FormAddProduct_AddsAndEdits_Click(object sender, EventArgs e)
        {
//Вот собственно тут и проблема. Значения переменным не присваиваются
            AddProduct dialog = new AddProduct(this);
//Если это из-за того что я сделал новый экземпялр класса AddProduct? Если да, тогда как работать с ранее созданным в обработчике btnAddProduct_Click?
            String name = dialog.tbAddNameProduct.Text;
            String producer = dialog.tbAddProducerProduct.Text;
            DateTime dateInstake = dialog.dtpAddDateInstakeProduct.Value;
            Boolean loss = (dialog.rbAddYesLoss.Checked ? true : false);

//Далее идет код, анализирующий значение переменных, вспомогательных полей формы и т.п.
            ..............................
        }
        //END
..........................
//И вот тут обработчик клика, вызывающий вторую форму
        private void btnAddProduct_Click(object sender, EventArgs e)
        {
            AddProduct addDialog = new AddProduct(this);
            addDialog.lbService.Text = "add";
            DialogResult result = addDialog.ShowDialog();

            if(result == DialogResult.OK)
                productBindingSource.Add(_showProductGenManager.GetProductManager().GetProductList().Last());
        }
.....................................

И соответственно во второй форме только конструктор
 
Код:
public AddProduct(ShowProduct obj)
        {
            InitializeComponent();
            bnAddProduct.Click += new EventHandler(obj.AddAndEdit);
        }


Подскажите пожалуйста как выкрутиться.
281
08 мая 2011 года
koodeer
1.2K / / 02.05.2009
Конечно, проблема из-за нового экземпляра формы. Нужно сделать её членом класса, а не локальной переменной. В методах использовать этот член. Примено так:
Код:
AddProduct dialog = new AddProduct(this);

private void FormAddProduct_AddsAndEdits_Click(object sender, EventArgs e)
{
    String name = dialog.tbAddNameProduct.Text;
    ...
}

private void btnAddProduct_Click(object sender, EventArgs e)
{
    dialog.lbService.Text = "add";
    DialogResult result = dialog.ShowDialog();
    ...
}
8.8K
08 мая 2011 года
Apach47
130 / / 14.06.2010
 
Код:
private AddProduct dialog = new AddProduct(this);

Так форму инстанцировать неполучается. Компилятор выдает
Цитата:
Error: Keyword 'this' is not available in the current context



А есть вообще способ получить данные, созданные в обработчике события формы2 в форме1, из которой вызвали форму2?

Просто сам шарп вторую неделю учу... Вот много вопросов и возникает...

8.8K
08 мая 2011 года
Apach47
130 / / 14.06.2010
тьфу... в конструктор надо было присваивание внести))) Последний вопрос снимается))

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог