Невозможно привести объект Type1 к типу Type2?
Я пытаюсь проверить кучу элементов управления в GroupBox
в приложении, основанном на форме.
Я не могу сопоставить ComboBox
приложению, чтобы оно распознало и сгенерировало ошибку, и оно делает это только для TextBox
.
private void groupBox1_Validating(object sender, CancelEventArgs e)
{
foreach (Control control in groupBox1.Controls)
{
string controlType = control.GetType().ToString();
var lst = new List<string>() { "System.Windows.Forms.TextBox" ,"System.Windows.Forms.ComboBox"};
//if (controlType == "System.Windows.Forms.TextBox")
if (lst.Contains(controlType, StringComparer.OrdinalIgnoreCase))
{
TextBox txtBox = (TextBox)control;
ComboBox combo = (ComboBox)control;
if (string.IsNullOrEmpty(txtBox.Text) && string.IsNullOrEmpty(combo.Text))
{
MessageBox.Show(txtBox.Name + " Can not be empty");
}
}
}
}
Вот ошибка, которую я получаю:
Невозможно привести объект типа ' System.Окна.Формы.Система ComboBox 'to type'.Окна.Формы.Текстовое поле".
5 ответов:
Поскольку вы просто хотите проверить свойство
Text
иName
, а также потому, что оба классаTextBox
иComboBox
наследуются от классаControl
, вам не нужно здесь выполнять приведение. Это должно работать для вас:foreach (Control control in groupBox1.Controls) { if (!lst.Contains(control.GetType().ToString(), StringComparer.OrdinalIgnoreCase)) continue; if (string.IsNullOrEmpty(control.Text) && string.IsNullOrEmpty(control.Text)) { MessageBox.Show(control.Name + " Can not be empty"); } }
Или с помощью Linq:
foreach (Control control in from Control control in groupBox1.Controls where lst.Contains(control.GetType().ToString(), StringComparer.OrdinalIgnoreCase) where string.IsNullOrEmpty(control.Text) && string.IsNullOrEmpty(control.Text) select control) { MessageBox.Show(control.Name + " Can not be empty"); }
В коде он приводит любое текстовое поле и любую комбинацию в текстовое поле и комбинацию.
Вам нужно бросить его в то, что он есть только.
private void groupBox1_Validating(object sender, CancelEventArgs e) { foreach (Control control in groupBox1.Controls) { if (control is ComboBox) { ComboBox combo = (ComboBox)control; if (string.IsNullOrEmpty(combo.Text)) MessageBox.Show(combo.Name + " Can not be empty"); } else if (control is TextBox) { TextBox txtBox = (TextBox)control; if (string.IsNullOrEmpty(txtBox.Text)) MessageBox.Show(txtBox.Name + " Can not be empty"); } } }
Если у groupbox есть только textbox и combobox, вы также можете сделать:
private void groupBox1_Validating(object sender, CancelEventArgs e) { foreach (dynamic control in groupBox1.Controls) { if (string.IsNullOrEmpty(control.Text)) MessageBox.Show(control.Name + " Can not be empty"); } }
Давайте подытожим, что вы хотите сделать:
- для каждого элемента управления внутри
groupBox1
- ... типа TextBox или ComboBox
- проверьте, что элемент управления не пуст, если это так, покажите окно сообщения
Вот некоторые важные моменты:
- каждый элемент управления, который наследуется от
Control
, имеет свойство publicText
, Вам не обязательно знать, является ли он текстовым полем или комбинацией для этой части- никакой контроль не является и текстовым полем и combobox (то есть ни один класс управления не наследуется от
TextBox
иComboBox
), поэтому один из этих приведений будет завершаться неудачей каждый раз, когда- вы могли бы использовать
as
вместо жесткого приведения, которое вернуло быnull
в приведении приведения, которое не может быть сделано, но с точкой 1. выше этого нет необходимостиИтак, вот переписанный код с вышеуказанным знанием:
private void groupBox1_Validating(object sender, CancelEventArgs e) { foreach (Control control in groupBox1.Controls) { if (!(control is TextBox || control is ComboBox)) continue; if (!string.IsNullOrEmpty(control.Text)) continue; MessageBox.Show(control.Name + " Can not be empty"); } }
Обратите внимание, что если вы хотите делать и другие вещи, которые должны были бы знать, является ли элемент управления текстовым полем или combobox, я бы вместо этого переписал его следующим образом:
private void groupBox1_Validating(object sender, CancelEventArgs e) { foreach (Control control in groupBox1.Controls) { var textbox = control as TextBox; if (textbox != null) { ... do your processing of textboxes here continue; } var combobox = control as ComboBox; if (combobox != null) { ... do your processing of comboboxes here continue; } ... do your processing of other controls here } }
Используйте оператор
is
, чтобы проверить, правильный ли у вас тип:if(control is TextBox) { TextBox txtBox = (TextBox)control; // Do something with txtBox if (string.IsNullOrEmpty(txtBox.Text)) { MessageBox.Show(txtBox.Name + " Can not be empty"); } } if(control is ComboBox) { ComboBox combo = (ComboBox)control; // Do something with combo if (string.IsNullOrEmpty(combo.Text)) { MessageBox.Show(combo.Name + " Can not be empty"); } }
As @LasseV.Карлсен отметил, что я выбирал длинный маршрут, индивидуально добавляя в каждый контроль. Я просто добавил контроль вместо чего-то, а не конкретные элементы управления.
Вот как теперь выглядит мой обновленный код:
foreach (Control control in groupBox1.Controls) { string controlType = control.GetType().ToString(); var lst = new List<string>() { "System.Windows.Forms.TextBox" ,"System.Windows.Forms.ComboBox"}; //if (controlType == "System.Windows.Forms.TextBox") if (lst.Contains(controlType, StringComparer.OrdinalIgnoreCase)) { // TextBox txtBox = (TextBox)control; // ComboBox combo = (ComboBox)control; if (string.IsNullOrEmpty(control.Text) && string.IsNullOrEmpty(control.Text)) { MessageBox.Show(control.Name + " Can not be empty"); } }