Обновление объектов Form1 из Form2 - PullRequest
0 голосов
/ 03 июля 2018

Я пытаюсь обновить значения Form1 из Form2, но ничего не происходит. Также нет ошибок, странно ...

Form1:

 public static Form2 f2{ get; set; } = new Form2();

 private void addButton1_Click(object sender, EventArgs e)
        {        
            f2.Show(); 
        }

Form2:

 public void button1_Click(object sender, EventArgs e)
    {
        Form f1 = new Form();
        f1.label2.ForeColor = Color.Red;
    }

Ничего не происходит. Я могу получить данные для своей формы2 из формы1, но я не могу отправить, я имею в виду, что могу, но ничего не происходит ... Почему? Спасибо

Ответы [ 4 ]

0 голосов
/ 03 июля 2018

Другие решения, упомянутые здесь, подойдут для вашего конкретного случая, но я рекомендую вам взглянуть на общую картину и разработать обобщенное решение, которое будет работать в большинстве случаев.

Ваша проблема сводится к тому, что делает что-то в одной форме на основе событий другой формы .

Лучший подход для этого, на мой взгляд:

  • Пусть Form1 сделает все свои действия.
  • Пусть Form2 сделает все свои действия.
  • Если вам нужно что-то сделать на Form1 на основе события, произошедшего на Form2, пусть Form2 уведомит Form1, что там что-то произошло, так что иди делай свое дело.
  • При необходимости передать данные от Form2 до Form1.

Поэтому я бы использовал для этой цели делегатов .

Представьте, что у вас есть Button и Label на вашем Form1. При нажатии на кнопку открывается Form2, на котором у вас есть еще Button. Нажатие этой кнопки на Form2 должно изменить цвет фона метки на Form1. Таким образом, наша установка будет выглядеть следующим образом. Вы не упомянули, если это Winforms или WPF, поэтому я использую WPF для моего удобства, но идея та же в любом из них.

Form1

enter image description here

Form2

enter image description here

В моем Form1 я бы объявил публичного делегата с такой подписью:

public delegate void NotifyEvent();

То есть этот делегат представляет метод, который не принимает параметров и имеет тип возврата void. Идея состоит в том, чтобы позволить Form2 вызывать метод в Form1, и этот метод по существу уведомляет о нажатии кнопки Form2. Итак, если бы у нас был способ вызвать метод, который находится в Form1 из Form2, мы могли бы затем уведомить Form1 о событии, происходящем в Form2 Со мной до сих пор?

Теперь, если я напишу такой метод в Form1 и позволю ему вызываться из Form2, это должно достичь нашей цели. Здесь lblDisp - это Label в Form1.

public void ButtonClickedOnForm2()
{
    lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
}

Для этого я бы определил делегат типа NotifyEvent в Form1, как показано ниже, и зарегистрировал для него метод ButtonClickedOnForm2(). Ваш код Form1 должен выглядеть следующим образом

public delegate void NotifyEvent();

public partial class Form1 : Window
{
    public NotifyEvent notifyDelegate;

    Form2 form2 = null;

    public Form1()
    {
        InitializeComponent();
        // This is 'registering' the ButtonClickedOnForm2 method to the delegate.
        // So, when the delegate is invoked (called), this method gets executed.
        notifyDelegate += new NotifyEvent(ButtonClickedOnForm2);
    }

    public void ButtonClickedOnForm2()
    {
        lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
    }

    private void BtnOpen_Click(object sender, RoutedEventArgs e)
    {
        // Passing the delegate to `Form2`
        form2 = new Form2(notifyDelegate);
        form2.Show();
    }
}

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

public partial class Form2 : Window
{
    NotifyEvent notifyDel;

    public Form2(NotifyEvent notify)
    {
        InitializeComponent();
        notifyDel = notify;
    }

    private void BtnOK_Click(object sender, RoutedEventArgs e)
    {
        // This invokes the delegate, which in turn calls the ButtonClickedOnForm2 method in Form1.
        notifyDel.Invoke();
    }
}

Теперь, когда кнопка нажата на Form2, она вызывает делегата. А на нашем Form1 мы сказали ему, что в случае вызова делегата он должен продолжить и выполнить метод ButtonClickedOnForm2. В этом методе мы написали код для изменения цвета фона метки. И это должно решить вашу проблему.


Передача данных

Кроме того, если вы хотите передать данные из Form2 в Form1, вы можете просто добавить параметры в определение делегата. Скажем, вы хотите передать string от Form2 до Form1. Затем вы изменили бы свой делегат так:

public delegate void NotifyEvent(string data);

А метод ButtonClickedOnForm2 вот так:

public void ButtonClickedOnForm2(string data)
{
    lblDisp.Content = data;
    lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
}

Затем в Form2 вызовите делегат, передав строку, например, так:

private void BtnOK_Click(object sender, RoutedEventArgs e)
{
    // This invokes the delegate, which in turn calls the ButtonClickedOnForm2 method in Form1.
    notifyDel.Invoke("I am from Form2");
}

Теперь нажатие кнопки на Form2 должно изменить цвет текста и фона надписи на Form1 следующим образом:

enter image description here

0 голосов
/ 03 июля 2018

Спасибо за идею конструктора. Во всяком случае (это) не работает для меня в глобальном масштабе. Поэтому мне нужно было упростить это до этого:

Форма 2 с конструктором:

  public Form1 _form1 { get; set; }
        public Form2(Form1 form1)
        {
            _form1 = form1;
            InitializeComponent();
        }

    public void button1_Click(object sender, EventArgs e)
        {
            _form1.label2.ForeColor = Color.Red;
        }
    }

Форма 1 создает новый объект с параметром каждый раз, когда требуется вызов (из-за 'this'):

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

Пока работает отлично ...

0 голосов
/ 03 июля 2018

попробуйте этот код

Форма 1:

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


public void ColorChange()
{
    label2.ForeColor = Color.Red;
}

Form2:

public Form1 f1;

public Form2(Form1 m)
{
    this.f1 = m;
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{ 
    f1.Show();
    f1.ColorChange();
}
0 голосов
/ 03 июля 2018

С помощью Form f1 = new Form(); вы создаете новую форму вместо доступа к уже открытой, и вы не вызываете f1.Show();, поэтому она никогда не будет отображаться. Вам нужна ссылка на тот, который открыт. Например. передать форму 1 в качестве параметра конструктора в форму 2.

В форме 2:

public partial class Form2 : Form
{
    private readonly Form1 _form1;

    public Form2 (Form1 from1)
    {
        _form1 = form1;
        InitializeComponent();
    }

    public void button1_Click(object sender, EventArgs e)
    {
        _form1.label2.ForeColor = Color.Red;
    }
}

В форме 1:

// Cannot be static as we need a reference to `this`
private Form2 _f2;
public Form2 f2 {
    get {
        if (_f2 == null) {
            _f2 = new Form2(this);  // Pass form 1 as parameter to form 2.
        }
        return _f2;
    }
}

private void addButton1_Click(object sender, EventArgs e)
{        
    f2.Show(); 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...