Example E1729
Visible to All Users

How to create an XPClassInfo descendant to dynamically build a persistent class structure

Files to look at:

This example is a variation of How to generate persistent classes at runtime based on a dataset with the difference that here we create a custom XPClassInfo class that provides metadata information for a type.
Then, we will use it to bind the GridControl to the XPServerCollectionSource, that is necessary to work in the Server Mode.

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)

Example Code

DynamicDataTable/DynamicDataTableClassInfo.cs(vb)
C#
using System; using System.Data; using DevExpress.Xpo; using DevExpress.Xpo.Metadata; using System.Collections.Generic; namespace DynamicDataTable { public class DynamicDataTableClassInfo : XPClassInfo { private readonly IList<XPMemberInfo> ownMembersCore = new List<XPMemberInfo>(); private readonly string tableNameCore; private readonly XPClassInfo baseClassCore; public DynamicDataTableClassInfo(XPDictionary dictionary, DataTable table) : base(dictionary) { if (table.PrimaryKey.Length != 1) throw new NotSupportedException(); baseClassCore = dictionary.QueryClassInfo(typeof(XPDataTableObject)); tableNameCore = table.TableName; foreach (DataColumn column in table.Columns) { XPCustomMemberInfo member = CreateMember(column.Caption, column.DataType); member.AddAttribute(new PersistentAttribute(column.ColumnName)); member.AddAttribute(new DisplayNameAttribute(column.Caption)); if (table.PrimaryKey[0] == column) member.AddAttribute(new KeyAttribute(column.AutoIncrement)); } dictionary.AddClassInfo(this); } public override bool CanGetByClassType { get { return false; } } public override string AssemblyName { get { return GetType().Assembly.FullName; } } public override XPClassInfo BaseClass { get { return baseClassCore; } } public override Type ClassType { get { return BaseClass.ClassType; } } protected override object CreateObjectInstance(Session session, XPClassInfo instantiationClassInfo) { return new XPDataTableObject(session, instantiationClassInfo); } public override string FullName { get { return tableNameCore; } } public override ICollection<XPMemberInfo> OwnMembers { get { return ownMembersCore; } } public override void AddMember(XPMemberInfo newMember) { ownMembersCore.Add(newMember); base.AddMember(newMember); } public override bool HasModifications(object theObject) { return PersistentBase.GetModificationsStore(theObject).HasModifications(); } public override void ClearModifications(object theObject) { PersistentBase.GetModificationsStore(theObject).ClearModifications(); } protected override bool CanPersist { get { return !HasAttribute(NonPersistentAttribute.AttributeType); } } } }
DynamicDataTable/Form1.cs(vb)
C#
using System; using System.Data; using DevExpress.Xpo; using DevExpress.Xpo.DB; using System.Windows.Forms; using System.Data.SqlClient; using System.Collections.Generic; namespace DynamicDataTable { public partial class Form1 : Form { private readonly string connectionString = "Data Source=(local);Initial Catalog=Northwind;Integrated Security=True"; private SqlConnection connection; private MSSqlConnectionProvider connectionProvider; private Session workSession; private Dictionary<string, DynamicDataTableClassInfo> dynamicClasses; public Form1() { InitializeComponent(); Init(); } protected void Init() { connection = new SqlConnection(connectionString); connectionProvider = new MSSqlConnectionProvider(connection, AutoCreateOption.None); IDataLayer dal = new SimpleDataLayer(connectionProvider); workSession = new Session(dal); string[] tablesList = connectionProvider.GetStorageTablesList(false); dynamicClasses = new Dictionary<string, DynamicDataTableClassInfo>(tablesList.Length); cmbTables.Properties.Items.AddRange(tablesList); cmbTables.SelectedIndexChanged += delegate(object sender, EventArgs args) { FillGrid(cmbTables.Text); }; } protected void FillGrid(string tableName) { if (grdTableBrowser.DataSource is IDisposable) { ((IDisposable)grdTableBrowser.DataSource).Dispose(); } grdTableBrowser.DataSource = null; gridView1.OptionsBehavior.Editable = false; gridView1.Columns.Clear(); DataTable dataTable = new DataTable(tableName); SqlDataAdapter adapter = new SqlDataAdapter(string.Format("SELECT * FROM [{0}]", tableName), connection); try { adapter.FillSchema(dataTable, SchemaType.Source); DynamicDataTableClassInfo dataTableClassInfo; if (!dynamicClasses.TryGetValue(tableName, out dataTableClassInfo)) { dynamicClasses.Add(tableName, new DynamicDataTableClassInfo(workSession.Dictionary, dataTable)); } XPServerCollectionSource dataSource = new XPServerCollectionSource(workSession, dynamicClasses[tableName]); grdTableBrowser.DataSource = dataSource; //grdTableBrowser.ServerMode = true; grdTableBrowser.ForceInitialize(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } }

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.