I am trying to work thru some sample code.
The code I am having a problem with is:
private ListControl GetSelectedList()
{
return (ListControl)FindControl(ddlControls.SelectedItem.Value);
}
ddlControls is a DropDownListBoxControl collection
What does the ddlControls.SelectedItem.Value return (its a numeric value, but I don't know what it represents)?
2nd question: What is return (ListControl)FindControl(ddlControls.SelectedItem.Value); ?
Thanks
SelectedItem.Value, as the name suggests, is the value of the currently selected item in the drop-down list. For example, if this were a list of months and someone had selected "September", this property has the value "September".
what is return (ListControl)FindControl(ddlControls.SelectedItem.Value);
FindControl is a method that looks up controls by their id. Using our example from before, it would try to find a control with the name "September". The (ListControl) at the beginning is a cast; the GetSelectedList() method is implicitly assuming that every possible answer you could get from ddlControls is the name of another ListControl. (This might not be a good idea depending on the circumstances.)
The result -- that is, the control whose id is the same as the currently selected value in ddlControls -- is then returned, and that's the result of GetSelectedList().
DropDownList Class in MSDN has the answer to the first question. In particular, it links to ListControl.SelectedItem, which is defined as:
If the list control allows only a single selection, use this property to get the individual properties of the selected item. If the list control allows multiple selections, use this property to get the properties of the lowest indexed item selected from the list control.
Similarly, Control.FindControl gives the answer to your second question. It's defined as:
Searches the current naming container for a server control with the specified id parameter.
Related
listBox_groupmakingrepairs is a listbox control on my form. When first loading the form, nothing is selected in the listbox and the code in the following 'if' statement will run because the condition is true.
if (listBox_groupmakingrepairs.Text == "")
{
Error = "You must indicate what group will be making the repairs.";
Con = listBox_groupmakingrepairs;
}
But, if I run the following code...
listBox_groupmakingrepairs.Text = "Cell";
Followed by this code...
listBox_groupmakingrepairs.ClearSelected();
The listbox will not have anything selected, yet it will cause the first code snippet above to be false and not run the code in the 'if' block. When I step through and check the value of 'listBox_groupmakingrepairs.Text' it is "Cell". Yet on the form, the listbox clearly has nothing selected.
Am I using the Text property of the Listbox control incorrectly? Or is this a bug? Or am I missing something altogether obvious?
The way I see it I have a property (Text) that seems to work well most of the time. But under certain conditions it returns a value that isn't the correct value anymore. Why is the Text property returning an old value that has since changed? Does this make logical sense to anyone who can explain it to me?
That is because the ListBox control of C# winform control handles both the Text property and the SelectedItem separately, but in a way together.
It works in the following way:
IF [SelectedItem is True i.e. Item is selected] THEN
Text property = SelectedItem.ToString()
ELSE IF [SelectedItem is False i.e. No Item is selected] THEN
Text Property will still assume its current value (or in a way previous value) unless its manually reset
So always in such cases donot forget resetting the Text property. Hope this helps...
Maybe I am a bit slow, but eventually I realized that Microsoft is the creator, so to them I will go for the answer.
Here is what I found:
According to Microsoft, the following code I was using is a correct way of selecting text in a listbox control.
listBox_groupmakingrepairs.Text = "Cell";
Then, also according to Microsoft, the following code I was using is a correct way of deselecting all items in a listbox.
listBox_groupmakingrepairs.ClearSelected();
Finally, also according to Bill Gates (see two links above) the Text property is also a correct way to retrieve the text of the first selected item.
string SelectedText = listBox_groupmakingrepairs.Text;
But, as I described in my original question above, when I evaluated the Text property WHEN NOTHING WAS SELECTED IN THE LISTBOX, it contained text. But Microsoft says "this property returns the text of the first selected item." WHICH IS FALSE. It should have returned null because there was nothing selected...yet it returned text which was NOT SELECTED.
So to answer my two questions in my original post:
"Am I using the Text property of the Listbox control incorrectly?" -- The answer is YES.
"Or is this a bug?" -- Yes, it is.
I have the code below
FooCB.DisplayMember = "FooNome";
FooCB.ValueMember = "Foo";
FooCB.DataSource = FooRepository.Instance.All();
FooCB.DataBindings.Add("SelectedItem", Bar, "Foo");
but when I display the form the SelectedItem is always the first.
What am I doing wrong?
I have been struggling a little with the behaviour of Winforms comboboxes and databinding recently and these are my observations (.Net4) when binding the ComboBox.DataSource to a list of items and also binding an object property to ComboBox.SelectedItem.
When binding a list of objects (in your case List<Foo>) to ComboBox.DataSource, the first object in the list is always shown in the combobox.
If you bind an object property to ComboBox.SelectedItem (in your case Bar.Foo) and that object property matches one of the combobox list objects then that object is displayed in the combobox. If the object property is null (Bar.Foo == null) or the object property is not in the combobox list then the first object is shown in the combobox.
Setting ComboBox.SelectedItem = null or ComboBox.SelectedIndex = -1 clears the displayed item on the combobox even though this seems to warn against it. And will set your bound object property to null.
If a user clears the combobox selection when using ComboBox.DropDownStyle == DropDown (with backspace) then the bound object property is set to null.
If you have implemented INotifyPropertyChanged on the object whose property is bound to Combobox.SelectedItem (Bar.Foo) and you programatically set the bound property to a value and that value appears in the combobox list then the changed value will be displayed. If you set the property to null or a value not in the list then the combobox displayed value will not change.
So what can you do about it? The only real issue I have is having no value displayed when my bound property is null so I have just been explicitly setting Combobox.SelectedItem = null as in point #3. You may be able to extend ComboBox and override the default behaviour but so far I have been content with an extra line of code here and there combined with using default values on non-nullable properties.
Probably you are missing some decleration. If you created the Combobox from the Tool Box, -I had the similar problem- you might want to add name of the Combobox's Name as a tag on XAML.
Other than that, if you created it dynamically by code, check if you are missing any decleration for class.
I can't tell from the OP's code whether I'm answering their question, but maybe this will help somebody reading this question. The ComboBox has four ways to set the current value:
SelectedIndex
SelectedItem
SelectedText
SelectedValue
You need to be consistent about what you're setting (and about which event handler you're using). You'll get an error if you set SelectedIndex to something dumb (less than -1 or longer than the list). However, you don't get errors setting the other three to something that doesn't exist for that type of selection.
Suppose you use a Dictionary (that's pseudo code) as a binding source and set DisplayMember = "Value" and ValueMember = "Key", the mapping would look like:
SelectedIndex - -1 to index of last item
SelectedItem - KeyValuePair<Key, Value>
SelectedText - Dictionary value
SelectedValue - Dictionary key
Supplying either value or key to SelectedItem will not generate an error, it will simply act like the OP has described. And that's why I thought this answer might help somebody.
I might also note that, if you're swapping out the contents of the ComboBox, it's not always safe to use SelectedIndex. Suppose the same basic kind of data is in the ComboBox, but selections are limited in some cases compared to others. Using SelectedIndex to persist a previous selection that was still valid in the new list of options is only going work if that previous selection held the exact same place in the list. You'd almost think this was the voice of very, very recent experience speaking...
I am encountering an exception when selecting a new value from a datagridviewcombobox(dropdown menu) control embedded in a datagridview. The combobox is populated by a BindingSource, which is populated with instances of my class. I can display the options in the menu properly, and select one, but changing focus to a new control (committing the change I guess) causes an exception to appear: Invalid Cast from System.String to myclass. The stack trace (if Im using that word right)shows the source was
System.Windows.Forms.DataGridView.PushFormattedValue
cascading down to
System.Convert.DefaultToType
A more explicit explanation is below (sorry its so long, but I wanted to make it reproducable):
I have an empty class called Occupant, with no properties(the problem exists when Occupant also has a string Name property so it's not that). I have a BindingSource called OccupantSource, with its DataSource pointing to Occupant.
I also have a class called Car, with one Occupant property called Driver.
In my Form_Load(), I call OccupantSource.AddNew() twice, and call CarSource.AddNew() once.
I have a DataGridView control, whose DataSource is CarSource (the BindingSource consisting of Cars). The DGV has one column, displaying the Driver property of the cars in CarSource. It is a DataGridViewComboBoxColumn, with DataPropertyName set to driver.
So what I want is to show rows of cars in the Datagridview, with one of the columns being a combobox I can dropdown and choose a driver from existing instances of Occupant. But I get the exception.
Is this something I'm misunderstanding? Can you not use instances of a class to populate a DataGridViewComboBox?
I ran into exactly the same problem and was scratching my head, using my google-fu for hours attempting to solve it. This link helped me finally gave me a good explanation.
http://www.pcreview.co.uk/forums/datagridview-combobox-column-error-listing-objects-t2344961.html
The way I fixed it was to change up the DisplayMember.
I had a refernce to 'Self' on the class that returned 'this' - I was using this for both DisplayMember and ValueMember thinking that it would just ToString() the property from DisplayMember.
Reading your explanation, you might not have DisplayMember and ValueMember set at all? If this is the case, try setting them correctly (and don't use a reference to 'this' for display member!) and it might fix it.
I am using the AutoCompleteBox in WPF, I populate the suggestions with a List that consists of four fields. When the user selects an item and I reach my eventHandler, i can see that
MyAutoCompleteBox.SelectedItem
is an object that has my four values, if i hover this text in the debugger i can see the four values listed, however i don't know how to access these values in the code.
I tried
List<Codes> selected = MyAutoCompleteBox.SelectedItem as List<Codes>;
where Codes is my List. selected returns as null and empty every time. Is there a way to get to these values? Thanks!
If you want the listing of items used as the backing collection for the AutoCompleteBox try...AutoCompleteBox.ItemsSource.
Can you try:
Codes selected = MyAutoCompleteBox.SelectedItem as Codes;
or
Codes[] selected = MyAutoCompleteBox.SelectedItem as Codes[];
It means that you cannot convert whatever MyAutoCompleteBox.SelectedItem is to a List.
How can I copy a collection of items in a comboBox to a StringCollection in my C# application? I'm only interested in capturing the string text for each item in their respective order. I am trying to make a MRU file list that is saved between sessions, so I would like to copy comboBox.Items to StringCollection Properties.Settings.Default.MostRecentlyUsedHexFiles. Any thoughts or suggestions you may have would be appreciated. Thanks.
You should be able to loop over the combobox.items and simply use stringcollection.Add() to add the string to the collection.
The tostring method will perform as described here:
Although the ComboBox is typically
used to display text items, you can
add any object to the ComboBox.
Typically, the representation of an
object in the ComboBox is the string
returned by that object's ToString
method. If you want to have a member
of the object displayed instead,
choose the member that will be
displayed by setting the DisplayMember
property to the name of the
appropriate member. You can also
choose a member of the object that
will represent the value returned by
the object by setting the ValueMember
property. For more information, see
ListControl.
So something like:
Foreach(object o in combobox.items)
{
//might need to access a datamember of the combobox's item if more complex solution is required, but this will probably do
stringcollection.Add(o.ToString);
}