Hello Infragistics team,
I am trying to bind the xamdatagrid to an observablecollection which contains a child observablecollection with dynamic columns. The columns for the child observablecollection do appear in the xamdatagrid, however, the values in all the records added to the collection are not visible in the grid.
Below is my source code:
-This is the code in my ViewModel:
dynamic employee = new Employee(); employee.FirstName = "Michael"; employee.LastName = "Jordan"; employee.SecondName = "Jordan2"; Employees.Add(employee); dynamic employee2 = new Employee(); employee2.FirstName = "Max"; employee2.LastName = "Headroom"; employee2.SecondName = "Jordan3"; Employees.Add(employee2);
Employees employees = new Employees(); public Employees Employees { get { return employees; } set { employees = value; OnPropertyChanged("Employees"); } }
-Below is the code for the observablecollection class with dynamic properties
public class Employees : ObservableCollection<dynamic>, ITypedList { #region ITypedList
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors) { ICustomTypeDescriptor emp = this.First(); return emp.GetProperties(); }
public string GetListName(PropertyDescriptor[] listAccessors) { return null; }
#endregion ITypedList }
public class Employee : DynamicObject, ICustomTypeDescriptor, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string property) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(property)); } }
#region DynamicObject
public Dictionary<string, object> properties = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result) { if (properties.ContainsKey(binder.Name)) { result = properties[binder.Name]; return true; } else { result = "Invalid Property!"; return false; } }
public override bool TrySetMember(SetMemberBinder binder, object value) { properties[binder.Name] = value; NotifyPropertyChanged(binder.Name); return true; }
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { dynamic method = properties[binder.Name]; result = method(args[0].ToString(), args[1].ToString()); return true; }
#endregion DynamicObject
public bool RemoveProperty(string property) { return properties.Remove(property); }
#region ICustomTypeDescriptor
public AttributeCollection GetAttributes() { throw new NotImplementedException(); }
public string GetClassName() { throw new NotImplementedException(); }
public string GetComponentName() { throw new NotImplementedException(); }
public TypeConverter GetConverter() { throw new NotImplementedException(); }
public EventDescriptor GetDefaultEvent() { throw new NotImplementedException(); }
public PropertyDescriptor GetDefaultProperty() { throw new NotImplementedException(); }
public object GetEditor(Type editorBaseType) { throw new NotImplementedException(); }
public EventDescriptorCollection GetEvents(Attribute[] attributes) { throw new NotImplementedException(); }
public EventDescriptorCollection GetEvents() { throw new NotImplementedException(); }
public PropertyDescriptorCollection GetProperties() { return ((ICustomTypeDescriptor)this).GetProperties(null); }
public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { PropertyDescriptorCollection props = new PropertyDescriptorCollection(null); foreach (KeyValuePair<string, object> property in properties) { props.Add(new DynamicPropertyDescriptor(property.Key)); } return props; }
public object GetPropertyOwner(PropertyDescriptor pd) { throw new NotImplementedException(); }
#endregion ICustomTypeDescriptor }
public class DynamicPropertyDescriptor : PropertyDescriptor { public DynamicPropertyDescriptor(string name) : base(name, null) { }
public override bool CanResetValue(object component) { return false; }
public override object GetValue(object component) { return Impromptu.InvokeGet(component, Name); }
public override void ResetValue(object component) {
}
public override void SetValue(object component, object value) { Impromptu.InvokeSet(component, Name, value); }
public override bool ShouldSerializeValue(object component) { return false; }
public override Type ComponentType { get { return typeof(object); } }
public override bool IsReadOnly { get { return false; } }
public override Type PropertyType { get { return typeof(object); } } }
Please help. Thank you.
Hello,
Thank you for your post. I have been looking into and I created a sample project for you following your scenario and everything seems to work ok on my side. If the sample doesn’t satisfies all your needs feel free to modify it, so it reproduces your behavior and send it back to me for further investigation.
Looking forward for your reply.
Hello Stefan,
Thanks for your sample, but the grid is not displaying the correct values. It is populating the data fields with Column Names (e.g. FirstName) instead of actual values (e.g. Michael). Please check that. Thank you.
Best regards,
Sherif
Hope you are well. I am trying to have checkboxes in one of the dynamically generated columns. So I use the following code in this example:
CheckBox check1 = new CheckBox(); check1.IsChecked = true;
employee.SecondName = check1;
Employees.Add(employee);
But when I run the application I get a string value in the xamdatagrid cell instead of the actual checkbox. Please advise how to resolve this. Thank you.
Hello Sherif,
Thank you for your feedback. I am glad that you resolved your issue and I believe that other community members may benefit from this as well.
Thanks again.
Thank you Stefan, it works perfectly now.
I have modified the sample you sent me, so now it has the functionality you want.
Hope this helps you.