iEditableObject class with a List type property
-
יום ראשון 19 פברואר 2012 23:15
Hi,
I want bind to datagridview an object where one of their properties is of type List. This object implements IEditableObject but the compiler don't allow me to bind.
I put an example:
public class Object1 : IEditableObject { private int p_Id; private List<Decimal> p_DecimalList; } public class Object1List : BindingList<Object1> { } public partial class Form1 : Form { bindingsource1.DataSource = Object1List; dataGridView1.DataSource = bindingsource1; }
Regards.
Albert Gassó
Ingeniero Técnico en Informática
Computer Software Engineer
כל התגובות
-
יום שני 20 פברואר 2012 02:08Binding requires public properties. But in case that is not the problem, you should always post your question with the error messages that you get.
Jose R. MCP
-
יום שלישי 21 פברואר 2012 06:40מנחה דיון
Hi Albert,
I agree with Jose and if your object implements IEditableObject interface, you need to implements IEditableObject.BeginEdit Method, IEditableObject.CancelEdit Method and IEditableObject.EndEdit Method.
The following link provides a simple implementation of the IEditableObject interface.http://msdn.microsoft.com/en-us/library/system.componentmodel.ieditableobject.aspx
If there is anything unclear, please let us know.
Best Regarsd,
Bob Wu [MSFT]
MSDN Community Support | Feedback to us
-
יום שלישי 21 פברואר 2012 09:39
Thanks you all, for your answers,
webJose, I don't have any error message, directly the compiler go out without message.
Bob, I know that if I use IEditableObject i must implement three methods (BeginEdit, CancelEdit, EndEdit), but I haven't put this methods in my example for simplifying.
I would add a comment, I use a List of integers because my goal is get an object with a dynamic property. If I use a List of integers, I can assign its size in run time, otherwise I must define the size of list in design time.
Regards
Albert Gassó
Ingeniero Técnico en Informática
Computer Software Engineer
- נערך על-ידי Albert Gassó יום שלישי 21 פברואר 2012 09:43
-
יום שלישי 21 פברואר 2012 09:42מנחה דיוןSo what do you mean by “ but the compiler don't allow me to bind.”;
Best Regards,Bob Wu [MSFT]
MSDN Community Support | Feedback to us
-
יום שלישי 21 פברואר 2012 11:40
Oops!, you're right, I have not explained very well!.
Sorry.
Albert Gassó
Ingeniero Técnico en Informática
Computer Software Engineer -
יום חמישי 23 פברואר 2012 08:26מנחה דיוןHi Albert,
Could you please give the following information?
Can you build the application?
Can you run the application?
Does the data displayed correctly?
You said that ”the compiler don't allow me to bind.”, so what does it shows? If nothing (error message or anything) shows, how can you know “the compiler don't allow me to bind”?
In addition, if you can share the code with us, it will help to solve this issue.
Best RegardsBob Wu [MSFT]
MSDN Community Support | Feedback to us
-
יום שישי 24 פברואר 2012 17:39
I have researched a little more, and I have seen that I have an error. But still, don't appear any error, and when I run application in DataGridView I don't see the column. Maybe by the following piece of code belonging to iEditableObject overriden methods:
#region IEditableObject Members public virtual void BeginEdit() { if (m_Editing == false) { m_Editing = true; m_OldValues = new Hashtable(); PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this); foreach (PropertyDescriptor property in properties) { m_OldValues.Add(property, property.GetValue(this)); } } } public virtual void CancelEdit() { if (m_Editing == true) { // Undo edit changes PropertyDescriptor property = null; foreach (DictionaryEntry entry in m_OldValues) { property = (PropertyDescriptor)entry.Key; property.SetValue(this, entry.Value); } // Clean up m_OldValues = null; m_Editing = false; } } public virtual void EndEdit() { if (m_Editing == true) { // Clean up m_OldValues = null; m_Editing = false; } } #endregionAt line
m_OldValues.Add(property, property.GetValue(this));
property.GetValue(this) where on property is List<Decimal> I get (Count = number of elements of the list).
Thanks
Albert Gassó
Ingeniero Técnico en Informática
Computer Software Engineer
Barcelona
- נערך על-ידי Albert Gassó יום שישי 24 פברואר 2012 17:47
-
יום ראשון 26 פברואר 2012 01:19
I just want to do that they ask in this thread:
Albert Gassó
Ingeniero Técnico en Informática
Computer Software Engineer
Barcelona -
יום שלישי 28 פברואר 2012 07:32מנחה דיוןHi Albert,
The link makes me more confused about your requirement. What are you trying to do?
Do you trying to bind the DataGridView to the List<Decimal> of the Object1 class? Suppose List<Decimal> has three Decimal, the bound DataGridView will have three columns?
Best Regards,Bob Wu [MSFT]
MSDN Community Support | Feedback to us
-
יום רביעי 29 פברואר 2012 08:00
Hi Bob,
I try to bind a custom object to datagridview. My custom object have a "normal" properties and a list of types, or list of objects property. Can be either (list of types, or list of objects). In my example, I put a list of types because I thought it would be clearer and the target was the same. I put a clarifying example:
public class InvoiceLine : FSBindingItem { private string p_IdProduct; private string p_IdInvoice; private int p_LineNumber; private List<UnitsSize> p_UnitsSizeList; public string IdProduct { get { return p_IdProduct; } set { p_IdProduct = value; } } public string IdInvoice { get { return p_IdInvoice; } set { p_IdInvoice = value; } } public int LineNumber { get { return p_LineNumber; } set { p_LineNumber = value; } } public List<UnitsSize> UnitsSizeList { get { return p_UnitsSizeList; } set { p_UnitsSizeList = value; } } } public class UnitsSize : FSBindingItem { private string p_IdSize; private decimal p_UnitsPerSize; public string IdSize { get { return p_IdSize; } set { p_IdSize = value; } } public decimal UnitsPerSize { get { return p_UnitsPerSize; } set { p_UnitsPerSize = value; } } } public class InvoiceLineList : BindingList<InvoiceLine> { } public partial class Form1 : Form { bindingsource1.DataSource = InvoiceLineList; dataGridView1.DataSource = bindingsource1; } public abstract class FSBindingItem : IEditableObject { protected bool m_Editing = false; protected Hashtable m_OldValues; #region Constructor public FSBindingItem() { } public virtual void BeginEdit() { if (m_Editing == false) { m_Editing = true; m_OldValues = new Hashtable(); PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this); foreach (PropertyDescriptor property in properties) { m_OldValues.Add(property, property.GetValue(this)); } } } public virtual void CancelEdit() { if (m_Editing == true) { // Undo edit changes PropertyDescriptor property = null; foreach (DictionaryEntry entry in m_OldValues) { property = (PropertyDescriptor)entry.Key; property.SetValue(this, entry.Value); } // Clean up m_OldValues = null; m_Editing = false; } } public virtual void EndEdit() { if (m_Editing == true) { // Clean up m_OldValues = null; m_Editing = false; } } } public class FSBindingList<T> : BindingList<T> { private bool p_isSorted; private PropertyDescriptor p_sortProperty; private ListSortDirection p_sortDirection; #endregion #endregion #region Properties #region Sorting Properties protected override bool IsSortedCore { get { return p_isSorted; } } protected override bool SupportsSortingCore { get { return true; } } protected override ListSortDirection SortDirectionCore { get { return p_sortDirection; } } protected override PropertyDescriptor SortPropertyCore { get { return p_sortProperty; } } #endregion #region Searching Properties protected override bool SupportsSearchingCore { get { return true; } } #endregion #endregion #region Methods #region Sorting Methods protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction) { // Get list to sort // Note: this.Items is t non-sortable ICollection<T> List<T> items = this.Items as List<T>; // Apply and set the sort, if items to sort if (items != null) { FSPropertyComparer<T> pc = new FSPropertyComparer<T>(property, direction); //QuickSort algorithm items.Sort(pc); p_isSorted = true; } else { p_isSorted = false; } p_sortProperty = property; p_sortDirection = direction; this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); } protected override void RemoveSortCore() { p_isSorted = false; this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); } public void Sort(PropertyDescriptor property, ListSortDirection direction) { this.ApplySortCore(property, direction); } #endregion #region Searching Methods /// <summary> /// Searches an FSBindingList for a particular item. /// </summary> /// <param name="property">The property to search.</param> /// <param name="key">The value to find.</param> /// <returns>The collection index of the found item.</returns> protected override int FindCore(PropertyDescriptor property, object key) { // Exit if no property specified if (property == null) return -1; // Get list to search List<T> items = this.Items as List<T>; // Traverse list for value foreach (T item in items) { // Test column search value string value = (string)property.GetValue(item); // If value is the search value, return the index of the data item if (((string)key).Equals(value)) return IndexOf(item); } return -1; } #endregion #region Persistence Methods /* These methods are used to serialize a collection to a file, * and to deserialize it from a file. They are intended for use * with standalone files, rather than a database. */ /* NOTE: BindingList<T> is not serializable, but List<T> is. * So, we cast the list to (List<T>) for loads and saves. */ /// <summary> /// Loads a collection from a serialized file. /// </summary> /// <param name="filename">The file path of the file to open.</param> public void Load(string filename) { this.ClearItems(); if (File.Exists(filename)) { BinaryFormatter formatter = new BinaryFormatter(); using (FileStream stream = new FileStream(filename, FileMode.Open)) { // Deserialize data list items ((List<T>)this.Items).AddRange((IEnumerable<T>)formatter.Deserialize(stream)); } } // Let bound controls know they should refresh their views this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); } /// <summary> /// Saves a collection to a serialized file. /// </summary> /// <param name="filename">The file path of the file to save.</param> public void Save(string filename) { BinaryFormatter formatter = new BinaryFormatter(); using (FileStream stream = new FileStream(filename, FileMode.Create)) { // Serialize data list items formatter.Serialize(stream, (List<T>)this.Items); } } #endregion #region Replace Methods public void Replace(int index, T item) { this.SetItem(index, item); } #endregion } }
I hope I have clarifying my problem.
Regards
Albert Gassó
Ingeniero Técnico en Informática
Computer Software Engineer
Barcelona -
יום חמישי 01 מרץ 2012 09:19מנחה דיוןHi Albert,
I’m afraid I still have the same question?
InvoiceLine class have four properties: IdProduct,IdInvoice,LineNumber and List<UnitsSize> UnitsSizeList. After binding an instance of InvoiceLineList, how many columns should DataGridView have?
IdProduct,IdInvoice,LineNumber and IdSize,UnitsPerSize or IdProduct,IdInvoice,LineNumber and numbers of IdSize,UnitsPerSize column?
Could you please help us picture the DataGridView and the Data in each cell?
Best Regards,
Bob Wu [MSFT]
MSDN Community Support | Feedback to us
-
יום חמישי 01 מרץ 2012 20:06
Hi Bob,
I am attaching a picture to clarify what I seek:
The columns Units per Size 7, Units per Size 8.5, etc... are a property of object UnitsSize.
This picture shows a lnvoiceLine with a properties:
IdInvoice, Date, LineNumber, IdProduct, Description, IdColor, List<UnitsSize> UnitsSizeList
Where I use the property "UnitsPerSize" of each UnitsSize object of list, which this list is inside of InvoiceLine object.
Regards.
Albert Gassó
Ingeniero Técnico en Informática
Computer Software Engineer
Barcelona -
יום שישי 02 מרץ 2012 19:37
I try this code, but it doesn't do that I want, because I have a List of UnitsSize objects:
public class InvoiceLineDescriptor : CustomTypeDescriptor { public InvoiceLineDescriptor(ICustomTypeDescriptor parent) : base(parent) { } public override PropertyDescriptorCollection GetProperties() { // get the attributes of InvoiceLine PropertyDescriptorCollection cols = base.GetProperties(); PropertyDescriptor unitsSizePD = cols["UnitsSize"]; PropertyDescriptorCollection p_size_child = unitsSizePD.GetChildProperties(); PropertyDescriptor[] array = new PropertyDescriptor[cols.Count + 2]; cols.CopyTo(array, 0); array[cols.Count] = new SubPropertyDescriptor(unitsSizePD, p_talla_child["IdSize"], "IdSize"); array[cols.Count + 1] = new SubPropertyDescriptor(unitsSizePD, p_talla_child["Units"], "Units"); PropertyDescriptorCollection newcols = new PropertyDescriptorCollection(array); return newcols; } public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { return (GetProperties()); } }
Albert Gassó
Ingeniero Técnico en Informática
Computer Software Engineer
Barcelona- נערך על-ידי Albert Gassó יום שישי 02 מרץ 2012 19:38