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();