We are evaluating the Silverlight data visualization controls. So far we are very happy with how the pivot grid, charts and data selector controls works together in displaying and working with data. However, up to this point we have only worked with predefined (at compile time) object classes where the data properties are known.
As we understand the controls read the data source (we use the flat data source) and derives the available data properties from the object class present in the data set delivered.
But we also have another scenario where the properties of the object class to visualize is not known at compile time. Based on conditions in the database the data object to visualize must be built dynamically at run time, and can have any number of dimensions and measures.
.NET framework allows to add object class properties at run time using the TypeDescriptionProvider API in System.ComponentModel. This could solve our problem, but unfortunately this API is not available for Silverlight applications. Instead we have option of using the DynamicObject API and using TryGetMember function to return dynamic property values.
However, the latter requires that the Infragistics data controls know which properties are available to be able to query their values. Is there a way to tell for instance the data selector which dimension and measure properties are available on the data objects in the data source? Or is there another approach to supply a data source with data objects having a arbitrary number of dimensions and measures?
Hi,
I created a behaviour using dynamic properties using examples in this thread. XamPivotGrid/XamPivotDataSelector still does not work(does not show anything in the selector). The documentation is not helpful too. Could you please look into the code below and suggest if i am missing something.
Thanks!
public class XamPivotDataSelectorBehavior : Behavior<XamPivotDataSelector> {
public Type ModelType { get { return (Type)(GetValue(ModelTypeProperty));} set { SetValue(ModelTypeProperty, value);} }
public static readonly DependencyProperty ModelTypeProperty = DependencyProperty.Register("ModelType", typeof(Type), typeof(XamPivotDataSelectorBehavior));
public IEnumerable DataSource { get { return (IEnumerable)GetValue(DataSourceProperty); } set { SetValue(DataSourceProperty, value); } }
public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource", typeof(IEnumerable), typeof(XamPivotDataSelectorBehavior));
private static void DataSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is XamPivotDataSelectorBehavior) { var obj = d as XamPivotDataSelectorBehavior; if (obj != null) { try { var grid = obj.AssociatedObject as XamPivotDataSelector; obj.DataSourceChanged(grid); // point datasource to flat source, no need to rebind
} catch (Exception ex) { } } } }
public static readonly DependencyProperty GridDataChangedProperty = DependencyProperty.Register("GridDataChanged", typeof(bool), typeof(XamPivotDataSelectorBehavior), new PropertyMetadata(DataSourceChanged));
public bool GridDataChanged { get { return (bool)GetValue(GridDataChangedProperty); } set { SetValue(GridDataChangedProperty, value); } }
protected virtual void DataSourceChanged(XamPivotDataSelector selector) { if (selector.DataSource == null) { var dataSource = new FlatDataSource();
selector.DataSource = dataSource;
}
((FlatDataSource)selector.DataSource).ItemsSource = GenerateTypedList(DataSource);
protected virtual IList GenerateTypedList(IEnumerable dataSource) {
DynamicTypeBuilder typeBuilder = new DynamicTypeBuilder { DynamicTypeName = ModelType.FullName, DynamicAssemblyName = "TrendsAssembly" };
var dynamicPropertyList = new List<DynamicTypePropertyInfo>(); foreach (PropertyInfo propertyInfo in ModelType.GetProperties(BindingFlags.Public)) { DynamicTypePropertyInfo dtpi = new DynamicTypePropertyInfo(); dtpi.PropertyName = propertyInfo.Name; dtpi.PropertyType = propertyInfo.PropertyType; dynamicPropertyList.Add(dtpi);
var dynamicType = typeBuilder.GenerateType(dynamicPropertyList);
//var type = dataSource.GetType().GetGenericArguments().First();
Type listType = typeof(List<>); Type genericListType = listType.MakeGenericType(dynamicType); var list = (IList)Activator.CreateInstance(genericListType);
foreach (var item in dataSource) {
var dynamicInstance = Activator.CreateInstance(dynamicType);
foreach (var pi in dynamicType.GetProperties(BindingFlags.Public)) { var modelPI = ModelType.GetProperty(pi.Name); pi.SetValue(dynamicInstance, modelPI.GetValue(item,null),null);
list.Add(dynamicInstance); }
return list;
I figured it out thanks.
IEnumerator enumerator = flatDataSource.ItemsSource.GetEnumerator(); while (enumerator.MoveNext()) { Type type = enumerator.Current.GetType(); PropertyInfo pi = type.GetProperty("Index Name"));
... // Now I can get and set the values
I am using XamPivotGrid. I want to edit a rows/columns in the PivotGrid. Instead of doing it via the grid, I want to modify the data source.
I use FlatDataSource as above. How ca I retrieve and edit FlatDataSource.itemSource dynamically.
Thanks
Hello,
If you meant the DynamicTypeBuilder it is a part of InfragisticsSL4.Olap.v10.3.dll and can be found under Infragistics.Olap namespace. And yes, this assembly is still part of v10.3. Have you tried to repair the product installation?
Best regards.Plamen.
Hello, I'm trying to do something similar in SL4 using the the 10.3 version of NetAdvantage and the InfragisticsSL4.Olap.v10.3.dll doesn't exist. I checked to see if it got renamed but it appears as if the assembly is no longer available in 10.3. Do you know if this can still be done in 10.3?
Thanks.