This question is locked. New answers and comments are not allowed.
Richard Harrigan
Top achievements
Rank 1
Richard Harrigan
asked on 17 Jan 2011, 12:13 AM
Hi
In the demo we have the following:
Expression<Func<Products, double>> expression = prod => prod.UnitPrice * prod.UnitsInStock;
How would you do this when the ItemsSource is generated dynamically as in the DataTable class?
Thanks
Rich
4 Answers, 1 is accepted
0
Hello Richard Harrigan,
Could you please tell me which implementation of DataTable for Silverlight you use?
Kind regards,
Yavor Georgiev
the Telerik team
Could you please tell me which implementation of DataTable for Silverlight you use?
Kind regards,
Yavor Georgiev
the Telerik team
Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
0
Richard Harrigan
Top achievements
Rank 1
answered on 18 Jan 2011, 05:22 PM
I downloaded it a few month ago. I don't know the version. I will paste all the DataTable code files. For later use how would I send you a zipped file.
The files are: DataTable.cs, DataRow.cs, DataColumn.cs, DynamicObject.cs, DynamicObjectBuilder.cs, TypeSignature.cs
Thanks
Rich
******************************************* DataTable.cs ************************************************************* using System; using System.Collections.Specialized; using System.Collections.Generic; using System.Linq; using System.Collections; using System.Collections.ObjectModel; namespace Telerik.Data { public class DataTable : IEnumerable, INotifyCollectionChanged { private IList<DataColumn> columns; private ObservableCollection<DataRow> rows; private IList internalView; private Type elementType; public event NotifyCollectionChangedEventHandler CollectionChanged; public IList<DataColumn> Columns { get { if (columns == null) { columns = new List<DataColumn>(); } return columns; } } public IList<DataRow> Rows { get { if (this.rows == null) { this.rows = new ObservableCollection<DataRow>(); this.rows.CollectionChanged += OnRowsCollectionChanged; } return rows; } } public DataRow NewRow() { return new DataRow(this); } private void OnRowsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Add: this.InternalView.Insert(e.NewStartingIndex, ((DataRow)e.NewItems[0]).RowObject); break; case NotifyCollectionChangedAction.Remove: this.InternalView.RemoveAt(e.OldStartingIndex); break; case NotifyCollectionChangedAction.Replace: this.InternalView.Remove(((DataRow) e.OldItems[0]).RowObject); this.InternalView.Insert(e.NewStartingIndex, ((DataRow) e.NewItems[0]).RowObject); break; case NotifyCollectionChangedAction.Reset: default: this.InternalView.Clear(); this.Rows.Select(r => r.RowObject).ToList().ForEach(o => this.InternalView.Add(o)); break; } } private IList InternalView { get { if (this.internalView == null) { this.CreateInternalView(); } return this.internalView; } } private void CreateInternalView() { this.internalView = (IList) Activator.CreateInstance(typeof(ObservableCollection<>).MakeGenericType(this.ElementType)); ((INotifyCollectionChanged) internalView).CollectionChanged += (s, e) => this.OnCollectionChanged(e); } internal Type ElementType { get { if (this.elementType == null) { this.InitializeElementType(); } return this.elementType; } } private void InitializeElementType() { this.Seal(); this.elementType = DynamicObjectBuilder.GetDynamicObjectBuilderType(this.Columns); } private void Seal() { this.columns = new ReadOnlyCollection<DataColumn>(this.Columns); } public IEnumerator GetEnumerator() { return this.InternalView.GetEnumerator(); } public IList ToList() { return this.InternalView; } protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { var handler = this.CollectionChanged; if (handler != null) { handler(this, e); } } } } ************************************************************* DataRow ************************************************************* using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Telerik.Data { public class DataRow { private readonly DataTable owner; private DynamicObject rowObject; protected internal DataRow(DataTable owner) { this.owner = owner; } public object this[string columnName] { get { return this.RowObject.GetValue<object>(columnName); } set { this.RowObject.SetValue(columnName, value); } } internal DynamicObject RowObject { get { this.EnsureRowObject(); return this.rowObject; } } private void EnsureRowObject() { if (this.rowObject == null) { this.rowObject = (DynamicObject) Activator.CreateInstance(this.owner.ElementType); } } } } *************************************************************** DataColumn.cs ******************************************************* using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Telerik.Data { public class DataColumn { public DataColumn() { this.DataType = typeof(object); } public Type DataType { get; set; } public string ColumnName { get; set; } } } **************************************************************** DynamicObject.cs ************************************************************* using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.ComponentModel; using System.Collections.Generic; using System.Reflection; namespace Telerik.Data { public abstract class DynamicObject : INotifyPropertyChanged { private readonly Dictionary<string, object> valuesStorage; public event PropertyChangedEventHandler PropertyChanged; protected DynamicObject() { this.valuesStorage = new Dictionary<string,object>(); } protected internal virtual T GetValue<T>(string propertyName) { object value; if (!this.valuesStorage.TryGetValue(propertyName, out value)) { return default(T); } return (T) value; } protected internal virtual void SetValue<T>(string propertyName, T value) { this.valuesStorage[propertyName] = value; this.RaisePropertyChanged(propertyName); } protected void RaisePropertyChanged(string propertyName) { this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) { var hanlder = this.PropertyChanged; if (hanlder != null) { hanlder(this, args); } } } } *************************************************************** DynamicObjectBuilder.cs ************************************************* using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Reflection.Emit; namespace Telerik.Data { internal class DynamicObjectBuilder { private static readonly Dictionary<TypeSignature, Type> TypesCache = new Dictionary<TypeSignature, Type>(); private static readonly AssemblyBuilder MicroModelAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynamicObjects"), AssemblyBuilderAccess.Run); private static readonly ModuleBuilder MicroModelModuleBuilder = MicroModelAssemblyBuilder.DefineDynamicModule("DynamicObjectsModule", true); private static readonly MethodInfo GetValueMethod = typeof(DynamicObject).GetMethod("GetValue", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly MethodInfo SetValueMethod = typeof(DynamicObject).GetMethod("SetValue", BindingFlags.Instance | BindingFlags.NonPublic); public static Type GetDynamicObjectBuilderType(IEnumerable<DataColumn> properties) { Type type; var signature = new TypeSignature(properties); if (!TypesCache.TryGetValue(signature, out type)) { type = CreateDynamicObjectBuilderType(properties); TypesCache.Add(signature, type); } return type; } private static Type CreateDynamicObjectBuilderType(IEnumerable<DataColumn> columns) { var typeBuilder = MicroModelModuleBuilder.DefineType("DynamicObjectBuilder_" + Guid.NewGuid(), TypeAttributes.Public, typeof(DynamicObject)); foreach (var property in columns) { var propertyBuilder = typeBuilder.DefineProperty(property.ColumnName, PropertyAttributes.None, property.DataType, null); CreateGetter(typeBuilder, propertyBuilder, property); CreateSetter(typeBuilder, propertyBuilder, property); } return typeBuilder.CreateType(); } private static void CreateGetter(TypeBuilder typeBuilder, PropertyBuilder propertyBuilder, DataColumn column) { var getMethodBuilder = typeBuilder.DefineMethod( "get_" + column.ColumnName, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.HasThis, column.DataType, Type.EmptyTypes); var getMethodIL = getMethodBuilder.GetILGenerator(); getMethodIL.Emit(OpCodes.Ldarg_0); getMethodIL.Emit(OpCodes.Ldstr, column.ColumnName); getMethodIL.Emit(OpCodes.Callvirt, GetValueMethod.MakeGenericMethod(column.DataType)); getMethodIL.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getMethodBuilder); } private static void CreateSetter(TypeBuilder typeBuilder, PropertyBuilder propertyBuilder, DataColumn column) { var setMethodBuilder = typeBuilder.DefineMethod( "set_" + column.ColumnName, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.HasThis, null, new[] { column.DataType }); var setMethodIL = setMethodBuilder.GetILGenerator(); setMethodIL.Emit(OpCodes.Ldarg_0); setMethodIL.Emit(OpCodes.Ldstr, column.ColumnName); setMethodIL.Emit(OpCodes.Ldarg_1); setMethodIL.Emit(OpCodes.Callvirt, SetValueMethod.MakeGenericMethod(column.DataType)); setMethodIL.Emit(OpCodes.Ret); propertyBuilder.SetSetMethod(setMethodBuilder); } } } ****************************************************** TypeSignature ************************************************************ using System; using System.Collections.Generic; using System.Linq; namespace Telerik.Data { internal class TypeSignature : IEquatable<TypeSignature> { private readonly int hashCode; public TypeSignature(IEnumerable<DataColumn> columns) { this.hashCode = 0; foreach (var column in columns.OrderBy(p => p.ColumnName)) { this.hashCode ^= column.ColumnName.GetHashCode() ^ column.DataType.GetHashCode(); } } public override bool Equals(object obj) { return ((obj is TypeSignature) && this.Equals((TypeSignature) obj)); } public bool Equals(TypeSignature other) { return this.hashCode.Equals(other.hashCode); } public override int GetHashCode() { return this.hashCode; } } }
0
Hi Richard Harrigan,
In this case you will have to build the expression tree to perform the calculation on your own, like this:
All the best,
Yavor Georgiev
the Telerik team
In this case you will have to build the expression tree to perform the calculation on your own, like this:
var parameter = Expression.Parameter(dataTable.ElementType);var myPropertyAccess = Expression.Property("MyProperty", parameter);var expressionLambda = Expression.Lambda(myPropertyAccess, parameter);column.Expression = expressionLambda;All the best,
Yavor Georgiev
the Telerik team
Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
0
Richard Harrigan
Top achievements
Rank 1
answered on 20 Jan 2011, 03:40 PM
Hi,
This code snippet is over my pay grade.
What would the code look like for the following:
GridViewExpressionColumn Balance = BudgetColumn - ActualColumn
Thanks
Rich
This code snippet is over my pay grade.
What would the code look like for the following:
GridViewExpressionColumn Balance = BudgetColumn - ActualColumn
Thanks
Rich