Как получить доступ к элементу управления формы для другой формы?

У меня есть два класса Form, один из которых имеет ListBox. Мне нужен сеттер для свойства SelectedIndex ListBox, который я хочу вызвать из второго Form.

В настоящий момент я делаю следующее:

Форма 1

public int MyListBoxSelectedIndex
{
     set { lsbMyList.SelectedIndex = value; }
}

Форма 2

private ControlForm mainForm; // form 1

public AddNewObjForm()
{
     InitializeComponent();
     mainForm = new ControlForm();           
}

public void SomeMethod()
{
     mainForm.MyListBoxSelectedIndex = -1;
}

Это лучший способ сделать это?

Ответ 1

Я обычно использую шаблон дизайна Singleton для чего-то вроде http://en.wikipedia.org/wiki/Singleton_pattern. Я сделаю основную форму, которую приложение запускает под синглоном, а затем создайте аксессоры для форм и элементов управления, которые я хочу коснуться в других областях. Другие формы могут либо получить указатель на элемент управления, который они хотят изменить, либо данные в основной части приложения, которое они хотят изменить.

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

Ответ 2

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

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

При таком подходе вы можете общаться по-разному.

Ссылка для скачивания для примера проекта

//Ваша форма1

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

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

    public string LabelText
    {
        get { return Lbl.Text; }
        set { Lbl.Text = value; }
    }
}

//Ваша форма2

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private Form1 mainForm = null;
    public Form2(Form callingForm)
    {
        mainForm = callingForm as Form1; 
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.mainForm.LabelText = txtMessage.Text;
    }
}

alt text
(источник: ruchitsurati.net)

alt text
(источник: ruchitsurati.net)

Ответ 3

Получите доступ к элементам управления формы следующим образом:

formname.controls[Index]

Вы можете использовать соответствующий тип элемента управления, например:

DataGridView dgv = (DataGridView) formname.Controls[Index];

Ответ 4

Легко, сначала вы можете получить доступ к другой форме следующим образом: (скажем, ваша другая форма Form2)

//in Form 1
Form2 F2 = new Form2();
foreach (Control c in F2.Controls)
         if(c.Name == "TextBox1")
            c.Text = "hello from Form1";

Чтобы это, вы просто пишете в TextBox1 в Form2 от Form1.

Ответ 5

Есть еще один способ, если вы не хотите перебирать элементы управления "ALL", как предложил Джо Дабонес. Сделайте функцию в Form2 и вызовите ее из Form1.

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    public void SetIndex(int value)
    {
        lsbMyList.SelectedIndex = value;
    }
}

public partial class Form1 : Form
{
    public Form2 frm;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        frm=new Form2();
        frm.Show();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm.SetIndex(Int.Parse(textBox1.Text));
    }
}