2016-01-14 3 views
-1

У меня есть форма (Form1) и класс (classx). У меня проблема с чтением текста из comboBox2 из Form1 в classx. Когда я нажимаю любой текст из comboBox2 во время отладки, он показывает мне «o: oo: oo», как будто я ничего не нажимал из comboBox2. Я знаю, что проблема состоит в строке, если(), потому что, если я оставлю это нравится: form1.comboBox2.SelectedItem.ToString() или form1.comboBox2.SelectedText.ToString() или form1.comboBox. Текст или любой другой вариант (который я просмотрел здесь в stackoverflow.com и в Google), он все еще показывает мне 0:00:00. Но, если я напишу это как: if («Рим» == Места [i]), он вычисляет значение для Рима, показывая 01:07:30. Как прочитать текст из выпадающего списка, который будет работать в моем коде?Не удается прочитать текст из ComboBox

Вот мой класс:

public class classx 
{   
    public string[] Places = new string[] { "Berlin", "Paris", "London", "Rome", "Tirana", "Istanbul" }; 
    public int[] Kilometers = new int[] { 50, 30, 70, 110, 40, 90 }; 
    public TimeSpan Times() 
    { 
     double length = 0; double hour = 0, minute = 0, seconds = 0; int hour1 = 0, minute1 = 0, second1 = 0; 
     Form1 form1 = new Form1(); 

     for (int i = 0; i <= 5; i++) 
     { 
      //this is the row which doesn't work 
      if (form1.comboBox2.SelectedText.ToString() == Places[i]) 
      { 
       length = Kilometers[i]; 
      } 
     } 
     hour = (length/80); 
     hour1 = Convert.ToInt32(Math.Truncate(hour)); 
     minute = (hour - Math.Truncate(hour)) * 60; 
     minute1 = Convert.ToInt32(Math.Truncate(minute)); 
     second = (minute - Math.Truncate(minute)) * 60; 
     second1 = Convert.ToInt32(Math.Truncate(second)); 
     TimeSpan time = new TimeSpan(Convert.ToInt32(hour), Convert.ToInt32(minute1), Convert.ToInt32(second1)); 
     TimeSpan TimeLength = new TimeSpan(hour1, minute1, second1); 
     return TimeLength; 
    } 
} 

А вот мой Form1

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

    } 

    public void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 

    } 

    public void comboBox2_SelectedIndexChanged(object sender, EventArgs e) 
    { 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     classx duration = new classx(); 

     MessageBox.Show("From " + comboBox1.Text + " to " + comboBox2.Text + " it takes around " + duration.Times()); 
    } 
} 

Там нет ошибок показаны. Любая идея, как получить текст из comboBox2?

Edit: Для будущих visitiors, которые на вопрос samea, этот ответ помог мне: https://stackoverflow.com/a/34794775/5749161

+0

SelectedText возвращает выделенную часть текущего текста. Вероятно, вы хотите 'comboBox2.SelectedItem.ToString()' – LarsTech

+0

, если я не пишу form1.comboBox2.SelectedItem.ToString(), появляется ошибка, потому что combobox2 не будет существовать в текущем контексте. Если я напишу form1.comboBox2.SelectedItem.ToString(), мой результат показывает 0:00:00 – noviceprogrammer

+0

Не похоже, что вы ссылаетесь на существующую форму. ClassX не должен знать ничего о вашей форме. Передайте ссылку на данные в свою функцию Times с соответствующими параметрами, исходящими из вашей формы. – LarsTech

ответ

1

Проблема в коде эта линия:

Form1 form1 = new Form1(); 

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

Изменить код так:

public TimeSpan Times(string place) 
    { 
     double length = 0; double hour = 0, minute = 0, seconds = 0; int hour1 = 0, minute1 = 0, second1 = 0; 


     for (int i = 0; i <= 5; i++) 
     { 
      //this is the row which doesn't work 
      if (Places[i] == place) 
      { 
       length = Kilometers[i]; 
      } 
     } 
     hour = (length/80); 
     hour1 = Convert.ToInt32(Math.Truncate(hour)); 
     minute = (hour - Math.Truncate(hour)) * 60; 
     minute1 = Convert.ToInt32(Math.Truncate(minute)); 
     second = (minute - Math.Truncate(minute)) * 60; 
     second1 = Convert.ToInt32(Math.Truncate(second)); 
     TimeSpan time = new TimeSpan(Convert.ToInt32(hour), Convert.ToInt32(minute1), Convert.ToInt32(second1)); 
     TimeSpan TimeLength = new TimeSpan(hour1, minute1, second1); 
     return TimeLength; 
    } 

, а затем в форму:

private void button1_Click(object sender, EventArgs e) 
    { 
     classx duration = new classx(); 
     var result = duration.Times(comboBox1.Text); 

     MessageBox.Show("From " + comboBox1.Text + " to " + comboBox2.Text + " it takes around " + result); 
    } 
+0

Спасибо за код, поскольку он работал почти отлично! Я изменил var result = duration.Times (comboBox2.Text); и значения начали появляться ... кроме Истабула. Он показывает мне 0:00:00. Другие города показывают результаты (спасибо много!), Но чтобы знать, правильно ли программа (согласно снимку экрана, который я получил), нужно нажать на instanbul и показать результат «01:07:30», но Стамбул это единственный город, который все еще показывает «0:00:00». Не могли бы вы взглянуть на это, чтобы результат тоже был для Instanbul? Я был бы очень благодарен! Редактировать: Я пытался увеличить предел контура до 6, но программа сломалась) – noviceprogrammer

+0

Единственная причина, по которой я могу думать, что они не записаны одинаково в массиве и combobox? – jvanrhyn

+0

... Я чувствую себя таким смущенным от этого. Большое спасибо за ваше время. Я действительно благодарю вас от глубины моего сердца! Надеюсь, я узнаю от вас новые вещи :) – noviceprogrammer

-1

Проверьте это:

string comboText = comboBox.SelectedValue.ToString(); 

Просто, чтобы показать, что это работает:

класс:

public class classzz 
{ 
    public string[] Places; 
    public int[] Kilometers; 

    public classzz() { 
     Places = new string[] { "Berlin", "Paris", "London" }; 
     Kilometers = new int[] { 50, 30, 70 }; 
    } 

    public String ShowValues(string text1, int value) { 
     return "The values selected were" + text1 + "-" + value.ToString(); 
    } 
} 

Форма:

public partial class Form1 : Form 
{ 
    protected classzz myClass; 

    public Form1() 
    { 
     InitializeComponent(); 
     myClass = new classzz(); 
     comboBox1.DataSource = myClass.Places; 
     comboBox2.DataSource = myClass.Kilometers; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     label1.Text = myClass.ShowValues(comboBox1.SelectedValue.ToString(), Int32.Parse(comboBox2.SelectedValue.ToString())); 
    } 
} 
+0

Вы хотите добавить его вот так: comboText = form1.comboBox2.SelectedValue.ToString(); для (int i = 0; i <= 5; i ++) { if (comboText == Места [i]) { длина = километры [i]; } } Потому что это сломало мою программу вниз, с ошибкой, говорящей: NullreferenceException был необработанным – noviceprogrammer

+0

Проверьте комментарий LarsTech на ваш исходный пост: SelectedItem - тот, который вы хотите. –

+0

Я думаю, что вы должны использовать 'SelectedValue', а' SelectedItem' - это то же самое, потому что вы можете получить значение от самого элемента, чтобы получить места –

0

ComboBox.SelectedText уже возвращает строку, поэтому нет необходимости использовать метод .ToString().

+0

Я тоже попробовал form1.comboBox.SelectedText, но это не сработало. Я показываю мне 0:00:00 – noviceprogrammer

1

У меня проблема с чтением текста из comboBox2 из Form1 в классx.

Из ваших строк кода в classx:

Form1 form1 = new Form1(); 

form1 является частью вашего элемента в методе classx. Затем, пока comboBox2access modifier находится в Form1public, то вы должны легко получить доступ к нему, как то, что вы сделали:

form1.comboBox2 //this can be easily done 

Но самая большая проблема здесь, так как вы объявляете новую форму в classx и вашей формы конструктора выглядит как это:

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

    } 

    public void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 

    } 

    public void comboBox2_SelectedIndexChanged(object sender, EventArgs e) 
    { 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     classx duration = new classx(); 

     MessageBox.Show("From " + comboBox1.Text + " to " + comboBox2.Text + " it takes around " + duration.Times()); 
    } 
} 

Смотрите, что нет никакого значения, выбранного для comboBox2 в инициализации формы. Это означает, что ваш comboBox2 всегда ничего не будет выбирать.Таким образом, вы ничего не получите слишком в classx

//this is the row which doesn't work 
//it is because nothing is ever selected in the first place 
if (form1.comboBox2.SelectedText.ToString() == Places[i]) 
{ 
    length = Kilometers[i]; 
} 

Вы можете поставить выбранный индекс в Form1 конструктора при необходимости быть:

public Form1() 
{ 
    InitializeComponent(); 
    comboBox2.SelectedIndex = 0; //assuming there is at least 1 item in the comboBox 
} 

Но лучшее не назвать ваш новый Форма в вашем classx. Вероятно, это пустая трата.

Таким образом, я предлагаю вам сделать это наоборот: вместо того form1 вызывается из метода в classx, вы должны лучше иметь form1, а затем в form1 у вас есть classx экземпляр (скажем, по имени classx classxInstance) , И в classx метод Times() в настоящее время вы не получаете вход. Измените его получить string вход, вы будете нуждаться в этом, чтобы получить вход от comboBox.SelectedText -> объявить его как это Times(string input) то вы это называете, как этот classxInstance.Times(comboBox2.SelectedText) от ваших Form1 и все будет намного лучше

Edit:

другой способ раунд будет выглядеть так,

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

    } 

    public void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 

    } 

    public void comboBox2_SelectedIndexChanged(object sender, EventArgs e) 
    { 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     classx duration = new classx(); 

     //Note that you should not use Text here, but selectedText 
     //Note that now your classx takes input from comboBox2.SelectedText  
     MessageBox.Show("From " + comboBox1.SelectedText + " to " + comboBox2.SelectedText + " it takes around " + duration.Times(comboBox2.SelectedText)); 
    } 
} 

И ваш classx будет выглядеть

public class classx 
{   
    public string[] Places = new string[] { "Berlin", "Paris", "London", "Rome", "Tirana", "Istanbul" }; 
    public int[] Kilometers = new int[] { 50, 30, 70, 110, 40, 90 }; 
    public TimeSpan Times(string input) //note the input string here 
    { 
     double length = 0; double hour = 0, minute = 0, seconds = 0; int hour1 = 0, minute1 = 0, second1 = 0; 
     //Form1 form1 = new Form1(); //you don't need this 

     for (int i = 0; i <= 5; i++) 
     { 
      //this is the row which doesn't work 
      if (input == Places[i]) //now you use input here 
      { 
       length = Kilometers[i]; 
      } 
     } 
     hour = (length/80); 
     hour1 = Convert.ToInt32(Math.Truncate(hour)); 
     minute = (hour - Math.Truncate(hour)) * 60; 
     minute1 = Convert.ToInt32(Math.Truncate(minute)); 
     second = (minute - Math.Truncate(minute)) * 60; 
     second1 = Convert.ToInt32(Math.Truncate(second)); 
     TimeSpan time = new TimeSpan(Convert.ToInt32(hour), Convert.ToInt32(minute1), Convert.ToInt32(second1)); 
     TimeSpan TimeLength = new TimeSpan(hour1, minute1, second1); 
     return TimeLength; 
    } 
} 
+0

Вы правы, я установил модификаторы для публики. Я попробовал предложенное редактирование «comboBox2.SelectedIndex = 0;» но результат был все еще 0:00:00, но я думаю, что вы правы в том, чтобы вызывать ** новую ** форму, сбросив значения. Но как я могу получить текст из формы без Form1 form1 = new Form1()? – noviceprogrammer

+0

Я предлагаю вам сделать это наоборот: у вас есть 'form1', а затем в' form1' у вас есть свой 'classx'. И в методе classx 'Times()' в настоящее время вы не получаете никакого ввода. Измените его, чтобы получить вход 'string' из' comboBox.SelectedText' -> объявить его как этот 'Times (ввод строки)', тогда вы вызываете его как этот 'Times (comboBox2.SelectedText)' из вашей 'Form1', и все будет быть намного лучше – Ian

+0

Прошу прощения за недостойность, но вы не могли вставить отредактированный код? Я был бы очень благодарен! – noviceprogrammer

0

У вас есть две проблемы.

1) SelectedText всегда будет "" для комбинированного блока, если вы не установите его на что-то еще, поэтому вам нужно использовать SelectedItem.

2) Вы создали новую форму, если у вас уже есть один, созданный в классе Program.

Ниже приведен полный функциональный пример.

using System; using System.Windows.Forms; 

namespace testforms { 
    static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 
    } } 

Вместо того, чтобы создавать форму, имеют форму create classx, например.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace testforms 
{ 
    public partial class Form1 : Form 
    { 
     private classx duration = null; 
     public Form1() 
     { 
      InitializeComponent(); 
      duration = new classx(this); 
     } 

     private void button1_Click_1(object sender, EventArgs e) 
     { 
      MessageBox.Show("From " + comboBox1.Text + " to " + comboBox2.Text + " it takes around " + duration.Times()); 
     } 
    } 

    public class classx 
    { 
     public string[] Places = new string[] { "Berlin", "Paris", "London", "Rome", "Tirana", "Istanbul" }; 
     public int[] Kilometers = new int[] { 50, 30, 70, 110, 40, 90 }; 

     Form1 form1 = null; 

     public classx(Form1 form) 
     { 
      form1 = form; 

      form1.comboBox1.Items.AddRange(Places); 
      form1.comboBox2.Items.AddRange(Places); 
     } 

     public TimeSpan Times() 
     { 
      double length = 0; double hour = 0, minute = 0, seconds = 0; int hour1 = 0, minute1 = 0, second1 = 0; 

      for (int i = 0; i <= 5; i++) 
      { 
       // change to SelectedItem because selected text will always be "" empty string. 
       if (form1.comboBox2.SelectedItem.ToString() == Places[i]) 
       { 
        length = Kilometers[i]; 
       } 
      } 
      hour = (length/80); 
      hour1 = Convert.ToInt32(Math.Truncate(hour)); 
      minute = (hour - Math.Truncate(hour)) * 60; 
      minute1 = Convert.ToInt32(Math.Truncate(minute)); 
      seconds = (minute - Math.Truncate(minute)) * 60; 
      second1 = Convert.ToInt32(Math.Truncate(seconds)); 
      TimeSpan time = new TimeSpan(Convert.ToInt32(hour), Convert.ToInt32(minute1), Convert.ToInt32(second1)); 
      TimeSpan TimeLength = new TimeSpan(hour1, minute1, second1); 
      return TimeLength; 
     } 
    } 
} 

В конструкторе установите свои выпадающие значки внутри, чтобы они могли быть инициализированы из класса x.

namespace testforms 
{ 
    public partial class Form1 
    { 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Windows Form Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.comboBox1 = new System.Windows.Forms.ComboBox(); 
      this.comboBox2 = new System.Windows.Forms.ComboBox(); 
      this.button1 = new System.Windows.Forms.Button(); 
      this.SuspendLayout(); 
      // 
      // comboBox1 
      // 
      this.comboBox1.FormattingEnabled = true; 
      this.comboBox1.Location = new System.Drawing.Point(36, 30); 
      this.comboBox1.Name = "comboBox1"; 
      this.comboBox1.Size = new System.Drawing.Size(121, 21); 
      this.comboBox1.TabIndex = 0; 
      // 
      // comboBox2 
      // 
      this.comboBox2.FormattingEnabled = true; 
      this.comboBox2.Location = new System.Drawing.Point(36, 91); 
      this.comboBox2.Name = "comboBox2"; 
      this.comboBox2.Size = new System.Drawing.Size(121, 21); 
      this.comboBox2.TabIndex = 1; 
      // 
      // button1 
      // 
      this.button1.Location = new System.Drawing.Point(36, 162); 
      this.button1.Name = "button1"; 
      this.button1.Size = new System.Drawing.Size(75, 23); 
      this.button1.TabIndex = 2; 
      this.button1.Text = "button1"; 
      this.button1.UseVisualStyleBackColor = true; 
      this.button1.Click += new System.EventHandler(this.button1_Click_1); 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(284, 261); 
      this.Controls.Add(this.button1); 
      this.Controls.Add(this.comboBox2); 
      this.Controls.Add(this.comboBox1); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      this.ResumeLayout(false); 

     } 

     #endregion 

     internal System.Windows.Forms.ComboBox comboBox1; 
     internal System.Windows.Forms.ComboBox comboBox2; 
     private System.Windows.Forms.Button button1; 
    } 
} 
0

Я изменил

var result = duration.Times(Combo2.Text); 

для всех городов у меня есть результаты, но только в Лондоне, у меня есть 00:00:00

+0

Единственная причина может заключаться в том, что текст в comboBox2 не «Лондон», а что-то вроде «лондон» или «lndon». Посмотрите на вектор тоже для опечаток – noviceprogrammer

Смежные вопросы