Simple problem: I am checking to see if a combobox has had an item selected with string.IsNullOrEmpty(). Problem is, even if is is selected, the error message appears. What am I doing wrong?
Here is my code:
private void button1Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(comboBox1.SelectedText))//here should skip to else - but doesn't
{
MessageBox.Show("You must select a conversion type", "Error");
}
else
{
if (comboBox1.SelectedText == "Currency")
{
double input = Convert.ToDouble(textBox1.Text);
if (!string.IsNullOrEmpty(comboBox2.SelectedText))
{
string type = comboBox2.SelectedText;
double result = convertCurrency(type, input);
if (result != -1)
{
label1.Text = Convert.ToString(result);
}
}
else
{
MessageBox.Show("You must select a conversion type", "Error");
}
}
else
{
MessageBox.Show("curency");
}
}
}
Note: This is my second ever C# program - so please don't yell at me if I'm being stupid.
Generally a few observations/suggestions.
First you're using string values and are basing logic on these values, you might want to look into using an Enum and binding all it's values to the combo box. Then use the SelectedItem property and compare it to the Enum.
When nothing is selected the SelectedItem will return NULL, another option is using SelectedIndex which will return -1 when no item has been selected.
So with the SelectedIndex it would become something like;
if (comboBox1.SelectedIndex == -1)//Nothing selected
{
MessageBox.Show("You must select a conversion type", "Error");
}
else
{
//Do Magic
}
Generally using string comparisons should only be done when anything "strong" like an int comparison or even better an enum comparison is not possible. (Maybe it's just me though but strings change to often and are just scary for this sort of stuff.)
For the enum suggestion possibly look at one of these links;
Binding an enum to a WinForms combo box, and then setting it
Load values of enum type into a combobox
Is it possible to load items from an Enum to a ComboBox in .NET 3.5?
Binding a ComboBox to an Enumeration
I'm not sure which .NET version and things you're using as binding is alot easier in WPF then in the old windows form (in my opinion).
from the MSDN doc, this answers your question exactly
You can use the SelectedText property to retrieve or change the
currently selected text in a ComboBox control. However, you should be
aware that the selection can change automatically because of user
interaction. For example, if you retrieve the SelectedText value in a
button Click event handler, the value will be an empty string. This is
because the selection is automatically cleared when the input focus
moves from the combo box to the button.
private void button2_Click(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex==-1)
{
MessageBox.Show("You must select a conversion type", "Error");
}
else
{
MessageBox.Show("Selected");
}
}
Another solution:
You can check whether the combobox has had an item selected by checking a condition with an Index which is out of range (which item is impossible to have), then, if it is not having a possible value, you can set it manually.
if (comboBox1.SelectedIndex == -1) //index out of range
{
//show the error message
comboBox1.SelectedIndex = 1; //set the first value to the combo box
}
else
{
//continue
}
Poor naming on microsoft's part. You should use comboBox.Text to get what you are looking for.
comboBox.SelectedIndex the index of the selected value
comboBox.SelectedItem if you using a DataSource, this is the item seleted in the datasource
comboBox.SelectedValuethe ValueMember of the Datasource or the currently selected value if you added your own Items
comboBox.Text The text that you see, even if it is not in the list
.SelectedText, refers to and text selected (highlighted) within the .Text
private void Resetbtn_Click(object sender, EventArgs e)
{
comboBox1.Items.Clear();
//Student is a combobox elements.Add again.
comboBox1.Items.Add("Student");
comboBox1.Items.Add("Staff");
}
Related
I have a list view with the multiselect property set to false. When the user clicks on it, I take the NAME property of the list view item and convert it to a decimal then feed that to a method that loads the correct record.
The code below works perfectly when I select one item regardless of how many items are in the list and regardless of which item I select.
private void ListInstruments_SelectedIndexChanged(object sender, EventArgs e)
{
ListViewItem selection = listInstruments.SelectedItems[0];
if (selection != null)
{
string strSelection = selection.Name;
SelectedInstrumentID = Convert.ToDecimal(strSelection);
LoadSelectedInstrument();
}
}
When I make a second selection (not multi-select, but a different selection from the listbox) I get an error referencing listInstruments.SelectedItems[0].
System.ArgumentOutOfRangeException Message=InvalidArgument=Value of
'0' is not valid for 'index'. Parameter name: index
Source=System.Windows.Forms
Any help would be appreciated.
It's possible, that no items are selected, and thus list.SelectedItems is empty; you are tring to get 0th item from the empty collection and thus have the exception thrown. The quick patch is
// instead of original
// ListViewItem selection = listInstruments.SelectedItems[0];
ListViewItem selection = list.SelectedItems.Count > 0
? listInstruments.SelectedItems[0] // the collection has at least one item
: null; // if the collection is empty
Or we can check if we have a selection and return when there's none
private void ListInstruments_SelectedIndexChanged(object sender, EventArgs e)
{
if (list.SelectedItems.Count <= 0)
return;
listViewItem selection = listInstruments.SelectedItems[0];
string strSelection = selection.Name;
SelectedInstrumentID = Convert.ToDecimal(strSelection);
LoadSelectedInstrument();
}
The AutoCompleteSource and AutoCompleteMode properties of the TextBox allow me to use automatic completion in textboxes.
I have bound directly a datatable as AutoCompleteSource of the textbox and it works well.
In some situations that the input words is not available in the sources, the auto completion has no result and so, i need to do something else in those situations.
How should i check whether the automatic completion result is empty?
Here is one approach you can take. The following code will get suggestions in the TextChanged event of the textbox when more than 3 characters have been entered. We go get the suggestions and then check if any suggestions were returned. If yes, we set the AutoCompleteCustomSource. Otherwise, we will do something--whatever we want to do.
private void textBox1_TextChanged(object sender, EventArgs e)
{
TextBox t = sender as TextBox;
if (t != null)
{
// Here I am making the assumption we will get suggestions after
// 3 characters are entered
if (t.Text.Length >= 3)
{
// This will get the suggestions from some place like db,
// table etc.
string[] arr = GetSuggestions(t.Text);
if (arr.Length == 0) {// do whatever you want to}
else
{
var collection = new AutoCompleteStringCollection();
collection.AddRange(arr);
this.textBox1.AutoCompleteCustomSource = collection;
}
}
}
}
I have a listview and this listview will be updated when a message is coming in.
The code below is about how I get the selected row's value.
private void CallTabLv_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string callDetailValue = "";
dynamic selectedCallDetail;
//When a row of call detail is selected, return the selected row's value only
if (LineBtn1.IsChecked == true)
{
selectedCallDetail = CallTabLv1.SelectedItem;
callDetailValue = selectedCallDetail.Value;
}
if (LineBtn2.IsChecked == true)
{
selectedCallDetail = CallTabLv2.SelectedItem;
callDetailValue = selectedCallDetail.Value;
}
if (string.IsNullOrEmpty(callDetailValue))
callDetailValue = string.Empty;
Clipboard.Clear();
Clipboard.SetText(callDetailValue);
}
It worked fine for first coming message and I could get the selected row's value. The problem is when second message came in, my application stopped and returned "Cannot perform runtime binding on a null reference".
By the way, to return single selected row' value, which one should be used: CallTabLv1.SelectedItem or CallTabLv1.SelectedItems[0]? As I tried, if the latter is used, it will return "ArgumentOutOfRange Exception" when second message is coming in.
Please help.
Update:
When the message is coming in, I update the listview by clearing the whole listview and then print it line by line. I'm not sure if it is caused by the way I update the listview.
So this is probably happening because you are clearing the collection in which you have now changed the selected item. Since the item can be null at that time the dynamic object will be unable to access the property "Value"
You are checking if a checkbox is checked which is not necessarily a condition of if the selected item will exist. I would suggest your code be updated as such.
private void CallTabLv_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string callDetailValue = "";
dynamic selectedCallDetail;
//When a row of call detail is selected, return the selected row's value only
if (LineBtn1.IsChecked == true)
{
selectedCallDetail = CallTabLv1.SelectedItem;
}
if (LineBtn2.IsChecked == true)
{
selectedCallDetail = CallTabLv2.SelectedItem;
}
// I think the 'invalid' casting is happening with the "selectedCallDetail.Value" as when you clear a listbox it is no longer selected.
callDetailValue = (selectedCallDetail != null) ? selectedCallDetail.Value : string.Empty;
Clipboard.Clear();
Clipboard.SetText(callDetailValue);
}
You should be using the SelectedItem as the SelectedItems collection may be null or empty, If you only ever want one result this is usually the best. also make sure your ListBox only allows for a single item to be selected so that the user cannot crash your code by selecting multiple items using SHIFT or CTRL click
I am making a very simple program. Need some help clearing out a textbox after performing a search. I have used the cboPrograms.Text = string.Empty; but I must not be putting it in the right place. After I choose an option it will not clear.
private void cboPrograms_SelectedIndexChanged(object sender, EventArgs e)
{
if (cboPrograms.Text == "MFValidation")
{
System.Diagnostics.Process.Start("C:\\Program Files (x86)\\Mozilla\\Mozilla.exe");
}
else if (cboPrograms.Text == "Add/Remove Programs")
{
System.Diagnostics.Process.Start("C:\\Program Files\\AddRemove\\addremove.exe");
cboPrograms.Text = string.Empty;
}
{
cboPrograms.Text = string.Empty;
}
}
That's because cboPrograms is not a TextBox but a ComboBox. (Text boxes do not have a SelectedIndexChanged event.)
To clear a combo box you do this:
cboPrograms.SelectedIdex = -1;
Also, reading the text of the combo box is not a good practice. You should have a collection of objects bound to the combo box. Get the selected object by calling SelectedItem and then working with the object's properties. The text you're seeing should just be a textual representation of the object. See here for more info.
You are missing an else statement before this code
{
cboPrograms.Text = string.Empty;
}
I have a ComboBox on a form. The DropDownStyle property of the ComboBox is set to DropDown, so that the user can select an item from the drop down list or type in some text manually.
When the user selects an item from the drop down list, I'd like to make some changes to the item's text before it appears in the ComboBox's text field. To use a very simplified example, let's say the drop down list contains items that consist of an ID and a description, like so:
101 Cat
102 Dog
103 Bird
When one of these items is selected, I'd like only the description to appear in the ComboBox's text field. So when "102 Dog" is selected, the string "Dog" should be displayed in the text field, ready to be edited by the user, and the items in the drop down list should be unchanged.
I thought I could just listen to, say, the SelectionChangeCommitted event of the ComboBox, and set the Text property of the ComboBox to whatever I like. But if I do this, the changes I make to Text are ignored, and the entire string ("102 Dog") is still displayed in the ComboBox.
So then I thought I should also update the SelectedIndex field to -1, to indicate to the ComboBox that the Text I'm setting is not an item in the drop down list. But this just clears the text field completely, regardless of what I change the Text property to.
So then I figured that SelectionChangedCommitted is the wrong event to be using, as it appears to fire too soon for my purposes (the Text property seems to only be updated with my selection after the SelectionChangeCommitted event handler has completed). But all other ComboBox events also fail to work, including SelectedIndexChanged and DropDownClosed.
I thought this would be pretty trivial to acheive. There's got to be a simple way to do this, and I'm sure I'm missing something obvious... any ideas?
You can try this:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex > -1)
{
string value = comboBox1.Items[comboBox1.SelectedIndex].ToString().Substring(4);
this.BeginInvoke((MethodInvoker)delegate { this.comboBox1.Text = value; });
}
}
Just to clarify, are you displaing "101 Cat", "102 Dog", etc. when the user dropdown the combo and displaying them when selected? Is 101 the key for the "Cat", 102 the key for the "Dog", and so on? If so, why are you displaying them and not only displaying the text of each item (if this is your requirement, apologize my answer). For what I understand, I'll configure the combobox valuemember to the property that returns you the 101, 102, etc. and the displaymember to the property that returns you the text of each items. This way, you'll already get what you want, i.e. displaying the "Cat", "Dog" and "Bird" text. Also, you can attach an event to the TextChanged event of the combo if you want furter processing.
The above solutions all work great, but fail when you want to use the style 'DropDownList' - which is a requirement for me, so I overengineered something else
Note: the below code has the same class reflect itself in both string formats. You can do it with a dictionary lookup and populate with .keys and .values instead, either way works.
EventCode
private bool activateCombobox = false;
private void myComboBox_DropDown(object sender, EventArgs e)
{
Foo.IsDroppedDown = true;
myComboBox.Items.Clear();
myComboBox.Items.AddRange(fooItems);
Foo.IsDroppedDown = false;
activateCombobox = true;
}
private void myComboBox_SelectedValueChanged(object sender, EventArgs e)
{
if (activateCombobox)
{
activateCombobox = false;
var selectedItem = myComboBox.SelectedItem;
myComboBox.Items.Clear();
myComboBox.Items.AddRange(fooItems);
myComboBox.SelectedItem = selectedItem;
}
}
and then our class code (change it to your classes ofc, this is just an example)
private Foo[] fooItems = new Foo[] { new Foo(1), new Foo(2), new Foo(3) };
private class Foo
{
public int index = 0;
public Foo() { }
public Foo(int index) { this.index = index; }
public string dropdownFoo { get { return $"Foo{index}"; } }
public string displayFoo { get { return $"Bar{index}"; } }
public override string ToString()
{
if (IsDroppedDown)
return dropdownFoo;
return displayFoo;
}
public static bool IsDroppedDown = false;
}