передача данных между combobox'ами разных форм

121
04 сентября 2021, 12:50

Подскажите как передать данные между комбобоксами с главной формы на дочернюю.

На главной форме заполняю

selectDBComboBox.Items.Add(new ConnectionString() { TypeDb = "SQL Server" });

На дочерней

public FormData(FormConnection fc)
        {
            InitializeComponent();
            comboBox1.Items.Add(fc.selectDBComboBox.SelectedValue);
        }

Но данные не переносятся, думаю что дело плевое, но всеже

Мое решение:

public FormConnection()
        {
            InitializeComponent();
            selectDBComboBox.Items.Add(new ConnectionString() { TypeDb = "Postgre" });
            selectDBComboBox.Items.Add(new ConnectionString() { TypeDb = "SQL Server" });
        }

Метод вызывающий вторую форму:

private void createBtn_Click(object sender, EventArgs e)
        {
            FormData formData = new FormData(this);
            formData.ShowDialog();
        }

На второй форме конструктор:

public FormData(FormConnection fc)
        {
            InitializeComponent();
            comboBox1.Text = fc.selectDBComboBox.Text;
        }
Answer 1

Для начала отделяем данные от UI, ибо нечего им там делать. Для этого сделаем простой класс который будет хранить данные для ComboBox-ов. Для примера модель будет предельно простой, расширить всегда можно по необходимости как и когда угодно.

class DataModel : INotifyPropertyChanged
{
    //научим модель уведомлять потребителя данных об их изменении
    public event PropertyChangedEventHandler PropertyChanged;
    public List<string> Data { get; } = new List<string> {"Val1", "Val2", "Val3", "Val4"};
    private int _selectedIndex = -1;
    public int SelectedIndex
    {
        get => _selectedIndex;
        set
        {
            if (_selectedIndex != value)
            {
                _selectedIndex = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedIndex)));
            }
        }
    }
}

Теперь воспользуемся модельным классом при создании форм. Начнем с диалогового окна:

class DialogForm : Form
{
    public DialogForm(DataModel model)
    {
        var cbox = new ComboBox();
        //ComboBox умеет работать с источником данных для строк "из коробки"
        cbox.DataSource = model.Data;
        //А текущий выбранный индекс придется привязать принудительно
        cbox.DataBindings.Add("SelectedIndex", model, "SelectedIndex", true, DataSourceUpdateMode.OnPropertyChanged);
        Controls.Add(cbox);
        var btn = new Button() { Text = "Close dialog" };
        btn.Location = new System.Drawing.Point(0, cbox.Location.Y + cbox.Height);
        CancelButton = btn;
        Controls.Add(btn);
    }
}

Теперь сделаем основное окно программы:

class MainForm : Form
{
    private readonly DialogForm _dialog;
    public MainForm(DataModel model)
    {
        _dialog = new DialogForm(model);
        var cbox = new ComboBox();
        cbox.DataSource = model.Data;
        cbox.DataBindings.Add("SelectedIndex", model, "SelectedIndex", true, DataSourceUpdateMode.OnPropertyChanged);
        Controls.Add(cbox);
        var btn = new Button() { Text = "Open dialog" };
        btn.Location = new System.Drawing.Point(0, cbox.Location.Y + cbox.Height);
        btn.Click += (s, e) => _dialog.ShowDialog();
        Controls.Add(btn);
    }
}

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

Ну и напоследок модифицируем запуск программы с учетом необходимости передать в форму модель через ее конструктор.

static class Program
{
    [STAThread]
    private static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm(new DataModel()));
    }
}

Всё. Оба ComboBox-а работают синхронно, в чем легко убедиться самостоятельно.

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

В коде не используется ни одного свойства или метода не описанного в документации .NET Framework, более того, там даже есть примеры использования.

Answer 2
public partial class Form1 : Form
{
    public delegate void OnText(object line);
    public static event OnText onText;
    public Form1()
    {
        InitializeComponent();
        Form2 f2 = new Form2();
        f2.Show();
    }
    private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
    {
        onText(comboBoxForm1.SelectedItem);
    }
}
public partial class Form2 : Form
{

    public Form2()
    {
        InitializeComponent();
        Form1.onText += Form1_onText;
    }
    private void Form1_onText(object line)
    {
        comboBoxForm2.Items.Add(line);
    }
}
Answer 3

может вместо

comboBox1.Items.Add(fc.selectDBComboBox.SelectedValue);

попробовать

foreach ( var item in fc.selectDBComboBox.Items ) comboBox1.Items.Add( item );

?

Answer 4

Один из легких путей, но не всегда правильный - глобальная переменная. Лучше использовать публичный метод или свойство. Другой метод - передача данных в конструктор Form2. Ну а там уже выбор за Вами!

READ ALSO
Подсчет сокращенных ссылок

Подсчет сокращенных ссылок

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

106
Ошибка pymysql.err.IntegrityError

Ошибка pymysql.err.IntegrityError

Пытаюсь сделать insert новостей в бдИ чтобы повторные новости не добавлялись

107
Как вывести теги?

Как вывести теги?

есть запрос для ввода статей

239
mysql left join не верно срабатывает

mysql left join не верно срабатывает

при таком запросе,

184