Combobox SelectedItem не работает правильно

Я пытаюсь извлечь выбранный элемент из списка, но не могу заставить его работать.

Form1 form = new Form1();
string cpuCount = form.comboBox1.SelectedItem.ToString();

Теперь это ничего не возвращает. НО, если я вставлю этот код в мой InitializeComponent(), он выбирает элемент с индексом = 3 и возвращает соответствующий элемент.

comboBox1.SelectedIndex = 3;

Почему это ведет себя так? Если я сейчас выберу, например, элемент с индексом = 5, он все равно будет думать, что выбранный элемент с индексом = 3.

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

Form1 - добавление всех элементов в выпадающие списки.

public partial class Form1 : Form
{
    Profile profile = new Profile();
    public Form1()
    {
        InitializeComponent();
        Profile profile = new Profile();
        string[] prof = profile.getProfiles();
        foreach (var item in prof)
        {
            comboBox5.Items.Add(Path.GetFileNameWithoutExtension(item));
        }

        int ram = 1024;
        for (int i = 0; i < 7; i++)
        {
            comboBox4.Items.Add(ram + " GB");
            ram = ram * 2;
        }

        int vram = 512;
        string size;
        for (int i = 0; i < 5; i++)
        {
            if(vram > 1000)
            {
                size = " GB";
            }
            else
            {
                size = " MB";
            }
            comboBox2.Items.Add(vram + size);
            vram = vram * 2;
        }

        for (int i = 1; i < 5; i++)
        {
            comboBox1.Items.Add(i * 2);
        }

        for (int i = 0; i < 5; i++)
        {
            comboBox3.Items.Add(i * 2);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string current = profile.currentProfile();
            profile.saveProfile(current);
        }

    }

Таким образом, button3 - моя кнопка "Сохранить". А вот и мой "Профиль"- класс

class Profile
{
    public string folder { get; set; }
    public Profile()
    {
        this.folder = "Profiles";
        if (!File.Exists(folder))
        {
            Directory.CreateDirectory(folder);
            File.Create(folder + "/default.cfg").Close();
        }
    }

    public string[] getProfiles()
    {
        string[] files = Directory.GetFiles(folder);
        return files;
    }

    public void saveProfile(string filename)
    {
        Form1 form = new Form1();
        string cpuCount = "cpuCount=" + form.comboBox1.SelectedItem;
        string RAM = "maxRAM=" + form.comboBox4.SelectedItem;
        string VRAM = "maxVRAM=" + form.comboBox2.SelectedItem;
        string threads = "cpuThreads=" + form.comboBox3.SelectedItem;
        string path = folder + "/" + filename;
        StreamWriter sw = new StreamWriter(path);
        string[] lines = { cpuCount, RAM, VRAM, threads };

        foreach (var item in lines)
        {
            sw.WriteLine(item);
        }



        sw.Close();

    }

    public string currentProfile()
    {
        Form1 form = new Form1();
        string selected = form.comboBox5.SelectedValue + ".cfg".ToString();
        return selected;
    }
}

Спасибо.

4 ответа

Решение

Проблема в том, что ничего не выбрано в вашем ComboBox, Вы создаете свою форму, а затем, без предварительного взаимодействия с пользователем, вы хотите получить SelectedItem который является нулевым в тот момент.

Когда вы создаете элемент управления ComboBox и заполняете его элементами, SelectedItem свойство null пока вы не установите его программно (например, используя comboBox1.SelectedIndex = 3) или путем взаимодействия с пользователем. В этом случае вы не делаете ничего из вышеперечисленного, и именно поэтому вы получаете упомянутую ошибку.

РЕДАКТИРОВАТЬ На основе отредактированного вопроса Измените свой код следующим образом: сначала измените saveProfile метод, чтобы вы могли передать четыре строки, которые вы пишете в текстовом файле. Обратите внимание, что вы могли бы альтернативно передать ссылку на форму, но я бы не советовал вам этого. Так что измените метод следующим образом:

public void saveProfile(string filename, string cpuCount, string RAM , string VRAM , string threads)
    {
        string path = folder + "/" + filename;
        using(StreamWriter sw = new StreamWriter(path)) 
        {
             sw.WriteLine("cpuCount=" + cpuCount);
             sw.WriteLine("maxRAM=" + RAM );
             sw.WriteLine("maxVRAM=" + VRAM );
             sw.WriteLine("cpuThreads=" + threads);
        }        
    }

А затем вызовите его из обработчика события button3 Click следующим образом:

private void button3_Click(object sender, EventArgs e)
{
            string current = profile.currentProfile();
            string cpuCount = this.comboBox1.SelectedItem.ToString();
            string RAM =  this.comboBox4.SelectedItem.ToString();
            string VRAM = this.comboBox2.SelectedItem.ToString();
            string threads = this.comboBox3.SelectedItem().ToString();
            profile.saveProfile(current, cpuCount, RAM, VRAM, threads);
}

Или в качестве альтернативы

private void button3_Click(object sender, EventArgs e)
{
            string current = profile.currentProfile();
            profile.saveProfile(current, this.comboBox1.SelectedItem.ToString(), this.comboBox4.SelectedItem.ToString(), this.comboBox2.SelectedItem.ToString(), this.comboBox3.SelectedItem().ToString());
}

Из того, что я вижу, ты звонишь form.comboBox1.SelectedItem.ToString() сразу после создания Form1, Это означает, что cpuCount переменная инициализируется сразу после создания формы, до того, как вы сможете изменить выбранный элемент с помощью мыши.

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

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

private void Form1_Load(object sender, EventArgs e)
{
this.comboBox1.SelectedItem= 5; // This will set the combo box to index 5
string cpuCount = this.comboBox1.SelectedText; // This will get the text of the selected item
}

так что вы получите значение элемента по индексу 5 в cpuCount переменная.

selected Предложение дает вам значения ПОСЛЕ того, как вы что-то выбрали, по умолчанию (когда вы запускаете свое приложение) в comoboBox ничего не выбирается, следовательно, оно отображает значение как нулевое, после выбора элемента вы можете использовать selectedItem в выпадающем списке, selectedIndex, Свойства selectedText и selectedValue.

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

чтобы связать данные со своим списком вы можете использовать,

// Bind your combobox to a datasource, datasource can be a from a database table, List, Dataset, etc..

 IDictionary<int, string> comboDictionary = new Dictionary<int, string>();
            comboDictionary.Add(1, "first");
            comboDictionary.Add(2, "second");
            comboDictionary.Add(3, "third");
            comboBox1.DataSource = comboDictionary;
            comboBox1.DisplayMember = "Key";
            comboBox1.ValueMember = "Value";

// 

И вот теперь вы можете использовать combobox1.SelectedIndex, чтобы просмотреть коллекцию элементов в источнике данных:), и она даст вам значение против ваших ключей при использовании combobox1.SelectedValue. Надеюсь это поможет.

В вашем ComoboBox нет предметов. Так что не вернется должным образом. Вы получаете доступ к выбранному значению в выпадающем списке после создания объекта формы.

И если в comboBox есть элементы, то ничего не выбирается. По умолчанию ничего не выбрано в comboBox. Вы должны установить это. Использовать этот. Что это возвращает? Установите comboBox.SelectedIndex, а затем получите selectedItem.

int selectedIndex = form.comboBox1.SelectedIndex;

Попробуй это. Добавьте некоторые элементы в ComboBox и затем выберите selectedItem.

Form1 form = new Form1();
form.comboBox1.Add("Item 1");
form.comboBox1.Add("Item 2");
form.comboBox1.Add("Item 3");
form.comboBox1.SelectedIndex = 1;
string cpuCount = form.comboBox1.SelectedItem.ToString();
Другие вопросы по тегам