DisplayMember not always being set in the CheckedListBox - c#

I have a CheckedListBox that I populate with a List of custom "DBitemtype" objects which I do through first setting the DataSource, then the DisplayMember, and ValueMember properties of the CheckedListBox "clbItemType". Now at runtime, the user has options to change the items so I have an event that rebinds the CheckedListBox with a different list of the same "DBitemtype" objects by first setting the DataSource to null, and then setting the DataSource to the new list, then setting the DisplayMember and ValueMember properties again to the exact same values like so:
clbItemType.DataSource = null;
clbItemType.DataSource = _SelectedItemTypes; // A List<DBitemtype>
clbItemType.DisplayMember = DBitemtype.Columns.ItemName; // String constant - value "ItemName"
clbItemType.ValueMember = DBitemtype.Columns.ID; // String constant - value "ID"
clbItemType.Refresh();
Both string constants used for DisplayMember and ValueMember describe public string properties in the DBitemtype class.
The issue I'm having is that sometimes the DisplayMember gets set with "ItemName" and sometimes it doesn't and just stays as "" when I step through the code. I can't seem to find a pattern as to why it happens only sometimes. No error or exception is thrown.
Al I could find was "If the new value of the DisplayMember cannot be set, the previous value is maintained." from the msdn article here CheckedListBox.DisplayMember Property
So I guess this is a 2-part question:
1) Has anyone else had this problem?
2) What are the conditions that will cause the DisplayMember to not be set?

I'm not sure if this helps, but I did find out that DisplayName does not like public fields (public int x;), only public properties (public int x { get; set; };).
So, I would try to make sure that ItemName or any other potential DisplayName values are in fact public properties of DBitemtype.

It might look the same, but:
clbItemType.DataSource = _SelectedItemTypes; // A List<DBitemtype>
clbItemType.DisplayMember = DBitemtype.Columns.ItemName; // String constant - value "ItemName"
clbItemType.ValueMember = DBitemtype.Columns.ID; // String constant - value "ID"
is not the same as:
clbItemType.DisplayMember = DBitemtype.Columns.ItemName; // String constant - value "ItemName"
clbItemType.ValueMember = DBitemtype.Columns.ID; // String constant - value "ID"
clbItemType.DataSource = _SelectedItemTypes; // A List<DBitemtype>
Set your members first, then change your DataSource. Changing a DataSource will fire event triggers and then return to the code block.

Related

ArgumentException when adding row to grid with DataGridViewComboBoxColumn

So I have a simple Grid on a WinForms app called dgAttributes. I use the following code to set up the columns:
dgAttributes.Columns.Clear();
dgAttributes.Columns.Add("Path", "Path");
dgAttributes.Columns.Add("Parameter", "Parameter");
DataGridViewComboBoxColumn comboBoxColumn = new DataGridViewComboBoxColumn
{
HeaderText = "DataConnection",
Name = "DataConnection",
DisplayMember = "ConnectionName",
ValueMember = "ServerName",
DataSource = _dataConnections
};
dgAttributes.Columns.Add(comboBoxColumn);
dgAttributes.Columns.Add("Tag", "Tag");
The _dataConnections variable contains a list of DataConnections and is always populated with at least one valid instance. I want the ConnectionName to be displayed in the Grid.
The DataConnection class looks like this:
public class DataConnection
{
public string ServerName;
public string UserName;
public string ConnectionName;
public override string ToString()
{
return ConnectionName;
}
}
But when I try to do the following:
DataConnection conn = _dataConnections.DefaultIfEmpty(_dataConnections.FirstOrDefault())
.FirstOrDefault(a => a.ConnectionName == point.DataConnection);
dgAttributes.Rows.Add(point.RelativePath, point.Element.Name, conn, point.Tag);
I get an ArgumentException (without InnerException) on the second line stating:
Field called ConnectionName does not exist.
Could someone tell me what I'm doing wrong? I think it's something very obvious but I really can't seem to figure it out. And I did look at examples and other posts but it looks like I'm doing the right thing.
It turned out that the information from MSDN should be taken very literally:
then the DisplayMember property must be set to the necessary property
name or column name.
Where "property" is the keyword here. Fields will not work. Thus after changing the string fields to properties, all was well.
I must say that the Exception message is pretty missleading. And I hope this saves someone, somewhere, some head scratching.
(source: http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcomboboxcolumn.displaymember%28v=vs.110%29.aspx)
For me, Setting DatagridView's "AutoSizeColumnsMode" value to "All cells" will give this error and setting the value back to "None" solved the problem

LINQ - Accessing a column with the column name as a string parameter

(Similar to this question)
I have tables called 'Questions' and 'FinalFigures':
Questions (QuestionID, Text, FinalFiguresColumnName)
FinalFigures (FinalFigureID, TotalDays, TotalCost, etc, etc)
'FinalFiguresColumnName' would have values like "TotalDays", "TotalCost", etc. Is there a simple way to loop through a set of Questions and have the 'Text' value saved to the corresponding column name on the 'FinalFigures' table?
Ie. instead of:
var item = new FinalFigure();
item.TotalDays = "x";
I need:
var item = new FinalFigure();
// access the column 'TotalDays' with its name as a string, not a property
You can use a bit of reflection to get the property value by the string name of the property instead of directly accessing it.
var value = (int)item.GetType().GetProperty("TotalDays").GetValue(item);
To set the value, simply call SetValue();
item.GetType().GetProperty("TotalDays").SetValue(item, value);

Data-Bound Combobox sometimes returning Value other than the one selected as displaymember

This is all the code related to the combox.
string SelectedDealer = Dealers.SelectedValue.ToString();
this.Dealers.DataSource = this.dealersBindingSource;
this.Dealers.DisplayMember = "DealerName";
this.Dealers.ValueMember = "DealerName";
The Dealers table has only two columns. What happens is, sometimes(one or two times/ application run) the
Dealers.SelectedValue.ToString();
returns the value of the other data-member,letsay Dealer-Id; right,that is Pretty weird.
Any help would be appreciated.
Try changing order of lines, who knows, it may help :) Maybe Combobox sets something default to ValueMember after setting its datasource if ValueMember is not previously set.
this.Dealers.DisplayMember = "DealerName";
this.Dealers.ValueMember = "DealerName";
this.Dealers.DataSource = this.dealersBindingSource;
string SelectedDealer = Dealers.SelectedValue.ToString();
Also check if something is in fact selected in your combobox: SelectedIndex of combobox souldn't be -1 (SelectedValue then may be unspecified, although it should throw NullPointerException)

Combo Boxes With Multiple Columns

I've read that combo boxes cannot have multiple columns. Which leaves me a bit stuck since what I want to do is display one field from a table, but return the corresponding value from a second field in the same table i.e.
I'd like to show CustomerNames in the combo box, but when the user selects a name, the CustomerID field is returned instead. Whats the best work around for this?
Best way is to use ComboBoxes DisplayMember and ValueMember properties
set the ComboBox.DisplayMember to the property you want to display. Use ValueMember for property you want to return. Then you can use the ComboBox.SelectedValue to get the current/selected ValueMember
You don't need multiple columns to implement it.
class Member
{
public string Name{get;set;}
public string Address{get;set;}
public int ID{get;set;}
public string Description
{
get
{
return string.Format("{0}, {1}", Name, Address);
}
}
}
var members = new []
{
new Member(){ID = 1, Name = "John", Address = "Addr 1"},
new Member(){ID = 2, Name = "Mary", Address = "Addr 2"}
};
m_ComboBox.DataSource = members;
m_ComboBox.DisplayMember = "Description"
m_ComboBox.ValueMember = "ID";
now you can access seleceted ID
var selectedID = m_ComboBox.CelectedValue();
The value of the ComboBoxItem does not have to be the same as the Text, consider using the ID as the value.
You can achieve the desired behaviour by setting the DisplayMember and ValueMember properties of the ComboBox to "CustomerName" and "CustomerID" respectively.
Take a look at the ValueMember property. You should set this to CustomerID. After you bind to your combobox, the actual field displayed to the user will be the CustomerName, but when you want to get the value of 'CustomerName', it will return the CustomerID.
When you want to get the value of the combobox, simply reference the SelectedValue.
If you are adamant about displaying both of these in the combobox, there are some hackish ways of doing this but I would recommend reviewing your requirements again and seeing if it is absolutely necessary.
Alternatively, you can define KeyValuePair objects with your intended Ids and text fields. Feed them to the combo, since its Items property is a collection of objects. Then, for retrieval use a cast like
var x = (KeyValuePair)combo.Items[0];
and then acces then Key and Value properties of x.
You can use Tag property of ComboBoxItem to store the value.

Get Value from ASPxComboBox get value

I have combobox with 2 values, ID and Name. I need to get ID from selected item, and I don't know how.
ASPxComboBox1.SelectedItem.GetValue(ID);
Not working.
ASPxComboBox1.TextField = "Name"; //This is the displayMember
ASPxComboBox1.ValueField = "ID"; //This is the valueMember
ASPxComboBox1.ValueType = typeof(String);
ASPxComboBox1.DataSource = DataTableWithIDandNameColumns;
ASPxComboBox1.DataBind();
String theID = Convert.ToString(ASPxComboBox1.Value);//The column in the datasource that is specified by the ValueField property.
OR:
String theID = Convert.ToString(ASPxComboBox1.SelectedItem.GetValue("ID"));//Any column name in the datasource.
Also:
String theName = Convert.ToString(ASPxComboBox1.SelectedItem.GetValue("Name"));
Use ASPxComboBox.Value property.
A combobox can only have one value per item and this is retrieved in your case by:
ASPxComboBox1.Value
See here in the documentation.
Since the value returned will be of type object, you will need to cast this to the type originally set, e.g. String. Then you will be able to work with it.
Usually the problem, when the ASPxComboBox's SelectedItem / SelectedIndex is incorrect, occurs when the ASPxComboBox's ValueType http://documentation.devexpress.com/#AspNet/DevExpressWebASPxEditorsASPxComboBox_ValueTypetopic property is specified incorrectly.
Ensure that the ValueType is set, corresponding to the "Data Type Mappings (ADO.NET)" http://msdn.microsoft.com/en-us/library/cc716729.aspx table.

Categories