This question is locked. New answers and comments are not allowed.
A while back I asked how to bind XML to the gridview. You gave me a lightweight DataTable class which worked fine. I have added some properties to the DataRow class to accept a Tag properties that stores the original XElement that it is created from.
I assumed that when I looked at the SelectedItem property of the GridView it would return the DataRow from the DataTable that was bound to the itemsource. Instead I get an object of type DynamicClass1. How can I reliably get the underlying DataRow object that matches the current selection?? I want this to work whether the grid is sorted / filtered or not. Below is your modified DataTable class and the usercontrol where I bind the xml to the gridview
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using System.Collections;
namespace Telerik.Data
{
public class DataTable : IEnumerable
{
List<DataColumn> columns = null;
public List<DataColumn> Columns
{
get
{
if (columns == null)
{
columns = new List<DataColumn>();
}
return columns;
}
}
List<DataRow> rows = null;
public List<DataRow> Rows
{
get
{
if (rows == null)
{
rows = new List<DataRow>();
}
return rows;
}
}
#region IEnumerable Members
IEnumerable enumerable = null;
public IEnumerator GetEnumerator()
{
if (enumerable == null)
{
var entries = new List<string>();
int i = 0;
foreach (DataColumn column in Columns)
{
string name = String.IsNullOrEmpty(column.ColumnName)?
String.Format("Column{0}", i) : column.ColumnName;
entries.Add(String.Format(@"{1}(it[""{0}""]) as {0}",
column.ColumnName, column.DataType.Name));
i++;
}
var projection = String.Format("new ({0})",
String.Join(",", entries.ToArray()));
enumerable = Rows.AsQueryable().Select(projection);
}
return enumerable.GetEnumerator();
}
#endregion
}
public class DataColumn
{
public DataColumn()
{
DataType = typeof(object);
}
public string DbName { get; set; }
public string Alias {get; set;}
public Type DataType { get; set; }
public string ColumnName { get; set; }
}
public class DataRow : Dictionary<string, object>
{
object tag;
public object Tag
{
get { return tag; }
set { tag = value; }
}
}
}
public partial class FTGenericReport : UserControl
{
FTGenericReportWindow pWindow;
public FTGenericReportWindow PWindow
{
get { return pWindow; }
set { pWindow = value; }
}
List<XElement> report ;
Telerik.Data.DataTable table = new Telerik.Data.DataTable();
List<XElement> schemanodes;
string schemams, schemans;
public FTGenericReport( )
{
InitializeComponent();
}
public void Init(List<XElement> report, List<XElement> sn)
{
this.report = report;
schemanodes = sn;
CreateColumns();
CreateRows();
gridview.DataLoaded += new EventHandler<EventArgs>(gridview_DataLoaded);
gridview.MultipleSelect = false;
try
{
gridview.ItemsSource = table;
}
catch
{
}
}
void gridview_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
}
void gridview_DataLoaded(object sender, EventArgs e)
{
int cnt = 0;
foreach (Telerik.Windows.Controls.GridViewColumn gc in gridview.Columns)
{
gc.Header = table.Columns[cnt].Alias;
gc.IsReadOnly = true;
cnt++;
}
}
private void CreateRows()
{
foreach (XElement datanode in report)
{
Telerik.Data.DataRow dr = new Telerik.Data.DataRow();
foreach (XElement xe in schemanodes)
{
dr.Tag = datanode;
string name = xe.Attribute(XName.Get("name")).Value;
IEnumerable<Telerik.Data.DataColumn> cls = table.Columns.Where(c => c.DbName == name);
if (cls.Count() == 1)
{
try
{
XElement rn = datanode.Elements().Single(c => c.Name.LocalName == name);
dr[cls.ElementAt(0).ColumnName] = rn.Value;
}
catch
{
dr[cls.ElementAt(0).ColumnName] = "";
}
}
}
table.Rows.Add(dr);
}
table.Rows.TrimExcess();
}
private void CreateColumns()
{
int cnt = 0;
foreach (XElement xe in schemanodes)
{
string dbname = xe.Attribute(XName.Get("name")).Value;
string name = FTSilverControls.Utility.XMLNameResolver(dbname, false);
Telerik.Data.DataColumn dc = new Telerik.Data.DataColumn() { ColumnName = "F" + cnt.ToString(), DataType = typeof(string),Alias =name , DbName = dbname};
table.Columns.Add(dc);
cnt++;
}
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
}
I assumed that when I looked at the SelectedItem property of the GridView it would return the DataRow from the DataTable that was bound to the itemsource. Instead I get an object of type DynamicClass1. How can I reliably get the underlying DataRow object that matches the current selection?? I want this to work whether the grid is sorted / filtered or not. Below is your modified DataTable class and the usercontrol where I bind the xml to the gridview
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using System.Collections;
namespace Telerik.Data
{
public class DataTable : IEnumerable
{
List<DataColumn> columns = null;
public List<DataColumn> Columns
{
get
{
if (columns == null)
{
columns = new List<DataColumn>();
}
return columns;
}
}
List<DataRow> rows = null;
public List<DataRow> Rows
{
get
{
if (rows == null)
{
rows = new List<DataRow>();
}
return rows;
}
}
#region IEnumerable Members
IEnumerable enumerable = null;
public IEnumerator GetEnumerator()
{
if (enumerable == null)
{
var entries = new List<string>();
int i = 0;
foreach (DataColumn column in Columns)
{
string name = String.IsNullOrEmpty(column.ColumnName)?
String.Format("Column{0}", i) : column.ColumnName;
entries.Add(String.Format(@"{1}(it[""{0}""]) as {0}",
column.ColumnName, column.DataType.Name));
i++;
}
var projection = String.Format("new ({0})",
String.Join(",", entries.ToArray()));
enumerable = Rows.AsQueryable().Select(projection);
}
return enumerable.GetEnumerator();
}
#endregion
}
public class DataColumn
{
public DataColumn()
{
DataType = typeof(object);
}
public string DbName { get; set; }
public string Alias {get; set;}
public Type DataType { get; set; }
public string ColumnName { get; set; }
}
public class DataRow : Dictionary<string, object>
{
object tag;
public object Tag
{
get { return tag; }
set { tag = value; }
}
}
}
public partial class FTGenericReport : UserControl
{
FTGenericReportWindow pWindow;
public FTGenericReportWindow PWindow
{
get { return pWindow; }
set { pWindow = value; }
}
List<XElement> report ;
Telerik.Data.DataTable table = new Telerik.Data.DataTable();
List<XElement> schemanodes;
string schemams, schemans;
public FTGenericReport( )
{
InitializeComponent();
}
public void Init(List<XElement> report, List<XElement> sn)
{
this.report = report;
schemanodes = sn;
CreateColumns();
CreateRows();
gridview.DataLoaded += new EventHandler<EventArgs>(gridview_DataLoaded);
gridview.MultipleSelect = false;
try
{
gridview.ItemsSource = table;
}
catch
{
}
}
void gridview_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
}
void gridview_DataLoaded(object sender, EventArgs e)
{
int cnt = 0;
foreach (Telerik.Windows.Controls.GridViewColumn gc in gridview.Columns)
{
gc.Header = table.Columns[cnt].Alias;
gc.IsReadOnly = true;
cnt++;
}
}
private void CreateRows()
{
foreach (XElement datanode in report)
{
Telerik.Data.DataRow dr = new Telerik.Data.DataRow();
foreach (XElement xe in schemanodes)
{
dr.Tag = datanode;
string name = xe.Attribute(XName.Get("name")).Value;
IEnumerable<Telerik.Data.DataColumn> cls = table.Columns.Where(c => c.DbName == name);
if (cls.Count() == 1)
{
try
{
XElement rn = datanode.Elements().Single(c => c.Name.LocalName == name);
dr[cls.ElementAt(0).ColumnName] = rn.Value;
}
catch
{
dr[cls.ElementAt(0).ColumnName] = "";
}
}
}
table.Rows.Add(dr);
}
table.Rows.TrimExcess();
}
private void CreateColumns()
{
int cnt = 0;
foreach (XElement xe in schemanodes)
{
string dbname = xe.Attribute(XName.Get("name")).Value;
string name = FTSilverControls.Utility.XMLNameResolver(dbname, false);
Telerik.Data.DataColumn dc = new Telerik.Data.DataColumn() { ColumnName = "F" + cnt.ToString(), DataType = typeof(string),Alias =name , DbName = dbname};
table.Columns.Add(dc);
cnt++;
}
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
}