I have specified a System.Windows.Forms.Binding for a textbox on my form. I have set the DataSourceNullValue property of the binding to 'DBNull.Value' and the NullValue property to 'string.Empty'. The DataSourceUpdateMode is set to 'OnValidation'. Everything works fine except one thing: when the textbox is bound to a datasource which has NULL set for the field the textbox is bound to and I enter the (empty) textbox and leave it (without changing anything), the datasource is updated from NULL to an empty string.
At MSDN - Binding.NullValue Property I have found, that the NullValue property is ignored for String-datatypes.
The desired behaviour is that the value in the datasource should stay NULL if the textbox is empty. How could I achieve this?
Related
I'm using Visual Studio, so at this point I have not written any code, it's all just property settings and drag-n-drop in the GUI. I have a form with several controls bound to a table. To populate a ComboBox on the form , I used the ComboBox task panel to bind the options to a view that has two fields (Type_Num and Type_Desc).
In the properties box for the ComboBox, I have my DisplayMember set to Type_Desc and my ValueMember set to Type_Num. When I run the form, the correct values are there in the dropdown, but when I select one and save, it tries to save the Type_Desc in the control instead of the Type_Num. What am I missing?
This happens when you have setup data-binding to Text property, while you need to save selected value. You should bind SelectedValue.
To change it at designer, expand the (+DataBindings) property group and remove data binding from text property and setup data binding to SelectedValue:
I am having a problem. I have a comboBox in that when I am entering
BlowMolding by coding comboSub1.Text = "BlowMolding".
It is automatically picking a value from list Blowmolding.
I know it is due to the fact that values are same except the case of "M"
and "m".
But in my application it creates problem.
So, Please tell me how to stop combo from picking the value
automatically and stick to the value I am assigning to it. Even if only
the case is changed.
If I understood your problem correctly, you are trying to set some value as text of your comboBox, and you also want that the text property should be set to whatever value you set explicitly.
If this the case then you should set the DropDownStyle property of your combo box to DropDown instead of DropDownList, which prevents you from setting value apart from what is have already in list.
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
you may also set this value via prperties window.
Try this:
comboSub1.SelectedIndex = comboSub1.Items.IndexOf("BlowMolding");
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 use VS2008 C# + Windows Forms. I can't understand why comboBox does not behave the way it should.
In Design mode, I added a comboBox to my form, and edit Items to add "A" and "B". Double-clicking brings me to SelectedIndexChanged event, which I edit to display the selected text with MessageBox.
private void comboBoxImageSet_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show(comboBoxImageSet.SelectedText);
}
When I run, and select "A" or "B" in the comboBox, the MessageBox appears, but nothing is written.
Why?
Thanks.
Here the differences between the selection properties of a ComboBox control.
SelectedIndex;
SelectedItem;
SelectedText;
SelectedValue.
The SelectedIndex property :
Gets or sets the index specifying the currently selected item.
Simply indicates the index of the selected item in the selection list. (Information provided for your kind information only. =))
The SelectedItem property :
Gets or sets currently selected item in the ComboBox.
The SelectedItem represents the element that is currently selected as per the ListControl of the ComboBox. That is why this is what you want to use, to answer your question.
The SelectedText property :
Gets or sets the text that is selected in the editable portion of a ComboBox.
That is, when you edit the TextBox portion of the ComboBox, the text that might be selected when you enter for edit, or any other type of text selection. This indeed does include any selection made through the ListControl portion of the ComboBox. For instance, if your ComboBox.DropDownStyle property is set to ComboBoxStyle.DropDownList, then you will never be able to select any text in the editable portion of the ComboBox. Despite, you're able to select another item within the its list. That is why it is not the right property to use to serve your purpose.
The SelectedValue property :
Gets or sets the value of the member property specified by the ValueMember property.
Only used when using DataBinding, in conjunction with the DisplayMember property. For instance, when you want to display the name of a customer, and select him by his database Id, then the DisplayMember should display the customer's name, and the ValueMember the Id. This way, when you select one customer, the SelectedValue changes and raises the SelectedValueChanged event inherited from the ListControl. (Information provided for your kind information only. =))
The SelectedText property returns the text that is marked in the combobox, not the selected item. If the combobox is editable you can mark a part of the text and the SelectedText property will return the marked text. Look here.
What you are interested in is the SelectedItem property or the SelectedValue property.
ComboBox.SelectedText
A string that represents the currently
selected text in the combo box. If
DropDownStyle is set to DropDownList,
the return value is an empty string
("").
Use SelectedItem instead of SelectedText
SelectedText:
Gets or sets the text that is selected
in the editable portion of a ComboBox.
That is, it gets the text that is currently marked.
You want to use SelectedItem.ToString().
I have an interesting data binding question related to combobox. Hope someone has some good suggestion.
I have a simple form, it contains a file picker and a comboxbox. Every time a file is picked, I read a list of strings from the file to a List object and I set comboBox.DataSource = listOfStrings.
In the form load event, I set comboBox.DataBindings.Add("SelectedItem", myObject, "PickedValue");
The purpose is clear: every time a string is selected from the combobox, I want to write the string to myObject.PickedValue.
That is the whole story.
Now I launch the form, rather than go pick a file, I check the combobox first. Of course, at this point, comboBox.DataSource is null, comboBox.SelectedItem is null, too. But the data binding on the comboBox is already setup (since the setting is in form load event). Now my focus cannot be moved from the combobox to anywhere else.
I think the reason is, when I try to check the combobox, it has null as SelectedItem. When I try to move the focus to somewhere else, the data binding of the combobox is triggered. Underlying, it tries to convert the selected item to string and update myObject.PickedValue with that converted string. Since you cannot convert a null to a string, the data binding validation fails, and the validation mechanism doesn't allow my focus to be moved elsewhere and I am sucked at this moment, cannot even move to pick a file.
My question is, what is the normal binding setup work-flow for my application scenario to prevent this trap? What is the correct order of setting up such a data binding so I can check my combobox before its data source is filled by something?
FYI, I tried to bind myObject.PickedValue to SelectedText property of the combobox (I noticed that SelectedText is a string and never be null, even when SelectedItem is null). But interestingly, even if I select something from the combobox, SelectedText is still empty string when data binding is triggered. What's wrong here?
Thanks for any help.
The failure is a little simpler than you describe: Your ComboBox will fail just because there is no selected item, because there's nothing to select from.
I would just disable the ComboBox if there's nothing to select from. It's pretty easy to do. Remember to hook up a PropertyChanged event in your data object; the binding source will find it automatically with reflection.
class MyData
{
public event PropertyChangedEventHandler PropertyChanged;
// ...
public HasListOfStrings { get { return ListOfStrings != null && 0 < ListOfStrings.Count; } }
private void LoadListOfStrings
{
// ... load the list of strings ...
if ( PropertyChanged) {
PropertyChanged(this, "ListOfStrings");
PropertyChanged(this, "HasListOfStrings");
}
}
}
In the designer, bind the 'Enabled' property of the 'ComboBox' to the HasListOfStrings property. You can do it in code with:
listOfStringsComboBox.Bindings.Add ("Enabled", bindingSource, "HasListOfStrings");
I also recommend you change the AutoValidate property of the container (or container's container) to EnableAllowFocusChange.
This doesn't seem right; it should be possible to set a string property to null. Possibly the focus problem lies elsewhere. Have you tried setting a breakpoint on your property setter to confirm your theory?
The SelectedText property of a combo box refers to text that has been selected in the text portion of the combobox. This only works if the dropdown style is set to combo. Basically it's the selected text of the text box portion of the combo control (the reason a combobox is called "combo" is because it is a combination of a textbox and a selection list). You would ordinarily expect this property to be empty unless the user was editing the text portion of the combo.
If you want a workaround for this problem that is consistent with a good user experience, try disabling the combo box on form load, then enabling it when a file is picked.