 |
|
 |
As described in this article, if you assign the DisplayMember BEFORE you assign the DataSource, the DisplayMember is wiped (ValueMember is not, go figure). Make this change to preserve it.
EDIT: point to note, this is a behaviour of the base ListControl, not of CheckedListBox
[DefaultValue("")] [AttributeProvider(typeof(IListSource))] [RefreshProperties(RefreshProperties.All)] [Browsable(true)] public new object DataSource { get { return base.DataSource; } set { string dm = this.DisplayMember; ((ListBox)this).DataSource = value; if (dm != this.DisplayMember) { this.DisplayMember = dm; } } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
This can be generalised to a CheckListBox<KeyType>
or even
CheckedListbox<KeyType,DataItemType>
and add a SelectedItemList method
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi, the idea looks very good and this is an agile approach which is not developed in the standard control. However, this error appears when trying to change the name of the object I have inserted to the form:
"Code generation for property 'ValueList' failed. Error was: 'Property accessor 'ValueList' on object 'cbxListSelectedOperations' threw the following exception:'Object reference not set to an instance of an object.''"
Any ideas?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi, i have the same error. I solved it un this way:
[Bindable(true), Browsable(true)] public List<object> ValueList { get { List<object> retArray = new List<object>(); PropertyDescriptor prop = null; PropertyDescriptorCollection propList = this.DataManager.GetItemProperties(); prop = propList.Find(this.ValueMember, false); object checkedItem; if (prop != null) { for (int i = 0; i < this.Items.Count; i++) { if (this.GetItemChecked(i)) { checkedItem = this.DataManager.List[i]; retArray.Add(prop.GetValue(checkedItem)); } } } return retArray; } }
public void SetValueList(List<object> Value) { if (this.DataManager != null) { List<object> myList = Value; PropertyDescriptor prop = null; PropertyDescriptorCollection propList = this.DataManager.GetItemProperties(); prop = propList.Find(this.ValueMember, false); object checkedItem; object valItem; if (prop != null) { for (int i = 0; i < this.Items.Count; i++) { checkedItem = this.DataManager.List[i]; valItem = prop.GetValue(checkedItem); if ((from c in myList where ValueType.Equals(c, valItem) select c).Count() == 1) this.SetItemCheckState(i, CheckState.Checked); else this.SetItemCheckState(i, CheckState.Unchecked); } } } }
This solution solve another problem: binding values to not integer type, like Guid.
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
Adding the attribute "ReadOnly(True)" also solves the problem. In this way, the code generator no longers makes a line in InitializeComponent that sets the property.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thank you for the great article. I failed to bind the ValueList member to a int list in data, I got the folowing runtime exception:
"Runtime error //Cannot bind to the property or column RoleReports on the DataSource. Parameter name: dataMember"
Here are my whole code, can you help me please?
public class Report { public int ReportID { get; set; } public string ReportName { get; set; } }
public class Role { public int RoleID { get; set; } public string RoleName { get; set; } public List<int> RoleReports = new List<int>(); }
public List<Report> ReportList = new List<Report>(); public BindingList<Role> RoleList = new BindingList<Role>();
public Form1() { InitializeComponent(); cCheckedListBox1.Location = new Point(12, 113); cCheckedListBox1.Size = new Size(184, 109); this.Controls.Add(cCheckedListBox1);
ReportList.Add(new Report { ReportID = 1, ReportName = "MCSE" }); ReportList.Add(new Report { ReportID = 2, ReportName = "English" }); ReportList.Add(new Report { ReportID = 3, ReportName = "CCNA" }); ReportList.Add(new Report { ReportID = 4, ReportName = "MCSD" });
RoleList.Add(new Role { RoleID = 1, RoleName = "Administrator", RoleReports = new List<int>() { 1, 2, 3, 4 } }); RoleList.Add(new Role { RoleID = 2, RoleName = "Manager", RoleReports = new List<int>() { 1, 2,3 } }); RoleList.Add(new Role { RoleID = 3, RoleName = "Salse", RoleReports = new List<int>() { 2, 4 } }); RoleList.Add(new Role { RoleID = 4, RoleName = "Student", RoleReports = new List<int>() { 3 } });
}
private void Form1_Load(object sender, EventArgs e) { L_RoleID.DataBindings.Add("Text", RoleList, "RoleID", true); TB_RoleName.DataBindings.Add("Text", RoleList, "RoleName", true); cCheckedListBox1.DataSource = ReportList; cCheckedListBox1.DisplayMember = "ReportName"; cCheckedListBox1.ValueMember = "ReportID"; //cCheckedListBox1.ValueList = new List<int>() { 2,4}; // worked cCheckedListBox1.DataBindings.Add("ValueList", RoleList, "RoleReports", true); // run time error //Cannot bind to the property or column RoleReports on the DataSource. Parameter name: dataMember }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I am answering my question! I changed the class role to this and it worked:
public class Role { public int RoleID { get; set; } public string RoleName { get; set; } public List<int> RoleReports { get; set; }
}
Thank you again for the goot article
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
 | Thanks  Thomas Wells | 10:26 17 Jan '09 |
|
 |
Just what I needed. Though I can't really say I understand why exposing the DataSource and related properties just makes it work I'm glad it does.
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
 | List  José Filipe Néis | 4:11 5 Jun '08 |
|
 |
Ricardo, nice job!
I'll use your code and adapt it to use an array of object instead of int, because my ID columns sometimes have strings on it.
Kind regards.
José Filipe
|
| Sign In·View Thread·PermaLink | 1.50/5 |
|
|
|
 |
|