Hello there,
I've been trying to make a grid as a Hierarchy Tabbed GridView (from Q3-2011-SP1 samples) that works with dynamic update on datasource, but I was unsuccessfull. On my grid's data-source I used a BindingSource binding to my object Employees (struct on memory), and simulated through a Timer (500ms) the parameter "FirstName" to be changed on my object. The value updated on my object was showed correctly on the grid cell, but I had a lot of problems with user events like re-ordering/resizing columns or rows.
I used a AutoResetEvent to prevent those conflicts, but my grid still firing two exceptions:
- When I try to re-order columns's headers by drag and drop and new data come at same time there's a failure on CellHeaderElement.ProcessDragDrop() method;
- When I try to use the columns header's Context Menu and new data comes the grid's method Refresh() closes the menu.
I tried to use a VirtualMode grid like Performance Sample but that's not what I need, once my grid must implements filtering\ordering and a nice template with details view.
Here's my code (based on yours, differences are highlighted), I would really appreciate if you guys tell me how to implement a Hierarchy Tabbed GridView without any user events conflicts or context menu closing:
namespace TabbedGridViewSemple
{
public partial class Form1 : Form
{
RadChart chart = new RadChart();
public PlenaDataSet dataSource = new PlenaDataSet();
public OrderDataSet orderSource = new OrderDataSet();
private int count = 0;
public AutoResetEvent eventsSync = new AutoResetEvent(true);
public Form1()
{
InitializeComponent();
}
#region Event handlers
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.radGridView1.BeginUpdate();
//Fill Data Source objects:
dataSource.Add(new Employee() { Address = "507 - Ave. E", BirthDate = new DateTime(1948, 12, 08), City = "Seattle", Country = "USA", EmployeeID = 1, FirstName = "Nancy", LastName = "Davolio", Title = "Sales Representative", Photo = new Bitmap(Properties.Resources.stock_logo) });
dataSource.Add(new Employee() { Address = "908 - Capital", BirthDate = new DateTime(1952, 02,19), City = "Tacoma", Country = "USA", EmployeeID = 2, FirstName = "Andrew", LastName = "Fuller", Title = "Vice President", Photo = new Bitmap(Properties.Resources.stock_logo) });
employeesBindingSource.DataMember = "Employees";
employeesBindingSource.DataSource = dataSource;
ordersBindingSource.DataMember = "Orders";
ordersBindingSource.DataSource = orderSource;
PrepareChartControl();
LoadDetailsTable();
LoadPerformanceTable();
this.radGridView1.UseScrollbarsInHierarchy = true;
this.radGridView1.ReadOnly = true;
radGridView1.MasterTemplate.ChildViewTabsPosition = TabPositions.Bottom;
this.radGridView1.EndUpdate();
}
void radGridView1_ChildViewExpanded(object sender, ChildViewExpandedEventArgs e)
{
eventsSync.Reset();
e.ChildRow.ChildViewInfos[0].ChildRows[0].Height = 152;
e.ChildRow.ChildViewInfos[2].ChildRows[0].Height = 152;
e.ChildRow.Height = 224;
eventsSync.Set();
}
void radGridView1_CellFormatting(object sender, CellFormattingEventArgs e)
{
eventsSync.Reset();
GridViewDataColumn column = e.CellElement.ColumnInfo as GridViewDataColumn;
if (column != null && column.OwnerTemplate.Caption == "Details")
{
if (column.FieldName == "FirstName")
{
e.CellElement.Text = "<html><b>Name:</b> " + e.CellElement.RowInfo.Cells["LastName"].Value + ", " +
e.CellElement.RowInfo.Cells["FirstName"].Value;
}
if (column.FieldName == "BirthDate")
{
e.CellElement.Text = string.Format("<html><b>Birth Date:</b> {0:d}", e.CellElement.RowInfo.Cells["BirthDate"].Value);
}
if (column.FieldName == "Title")
{
e.CellElement.Text = "<html><b>Title:</b> " + e.CellElement.RowInfo.Cells["Title"].Value;
}
if (column.FieldName == "Address")
{
e.CellElement.Text = "<html><b>Address:</b> " + e.CellElement.RowInfo.Cells["Address"].Value;
}
if (e.CellElement is GridImageCellElement)
{
((GridImageCellElement)e.CellElement).ImageLayout = ImageLayout.Zoom;
}
}
if (column != null && column.OwnerTemplate.Caption == "Performance")
{
if (e.CellElement.RowInfo.Tag == null)
{
chart.Series.Clear();
chart.Series.Add(GetRowData((GridViewRowInfo)e.CellElement.RowInfo));
e.CellElement.RowInfo.Tag = chart.GetBitmap();
}
e.CellElement.Image = e.CellElement.RowInfo.Tag as Image;
e.CellElement.DrawBorder = false;
e.CellElement.DrawFill = false;
e.CellElement.Text = "";
e.CellElement.Padding = new Padding(10, 0, 0, 0);
}
eventsSync.Set();
}
void radGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e)
{
eventsSync.Reset();
if (e.CellType == typeof(GridDetailViewCellElement))
{
e.CellElement = new CustomDetailViewCellElement(e.Column, e.Row);
}
eventsSync.Set();
}
#endregion
void PrepareChartControl()
{
chart.Size = new Size(600, 150);
chart.Chart.ChartTitle.Visible = false;
chart.Legend.Visible = false;
chart.Appearance.Border.Visible = false;
chart.Appearance.FillStyle.MainColor = Color.White;
chart.AutoLayout = true;
chart.ChartTitle.Visible = false;
chart.ChartTitle.TextBlock.Text = "";
chart.PlotArea.Appearance.Border.Visible = false;
chart.PlotArea.Appearance.FillStyle.FillType = FillType.Solid;
chart.PlotArea.Appearance.FillStyle.MainColor = Color.Transparent;
chart.PlotArea.Appearance.FillStyle.SecondColor = Color.Transparent;
chart.PlotArea.YAxis.Appearance.CustomFormat = "C0";
chart.PlotArea.YAxis.LabelStep = 2;
chart.PlotArea.XAxis.Appearance.ValueFormat = ChartValueFormat.ShortDate;
chart.PlotArea.XAxis.Appearance.CustomFormat = "dd/MM";
}
void LoadDetailsTable()
{
DataTable table = new DataTable("Details");
table.Columns.Add("EmployeeID", typeof(int));
table.Columns.Add("Photo", typeof(Bitmap));
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("Title", typeof(string));
table.Columns.Add("Address", typeof(string));
table.Columns.Add("City", typeof(string));
table.Columns.Add("BirthDate", typeof(DateTime));
table.Columns.Add("Country", typeof(string));
foreach (Employee row in dataSource.Employees)
{
table.Rows.Add(row.EmployeeID, row.Photo, row.FirstName,
row.LastName, row.Title, row.Address, row.City, row.BirthDate, row.Country);
}
GridViewTemplate template = new GridViewTemplate();
template.Caption = "Details";
template.DataSource = table;
template.AllowRowResize = false;
template.ShowColumnHeaders = false;
template.Columns["Photo"].Width = 125;
template.Columns["City"].Width = 70;
template.Columns["Country"].Width = 70;
template.Columns["FirstName"].DisableHTMLRendering = false;
template.Columns["Title"].DisableHTMLRendering = false;
template.Columns["BirthDate"].DisableHTMLRendering = false;
template.Columns["Address"].Width = 200;
template.Columns["Address"].DisableHTMLRendering = false;
this.radGridView1.Templates.Insert(0, template);
GridViewRelation relation = new GridViewRelation(this.radGridView1.MasterTemplate);
relation.ChildTemplate = template;
relation.ParentColumnNames.Add("EmployeeID");
relation.ChildColumnNames.Add("EmployeeID");
this.radGridView1.Relations.Add(relation);
HtmlViewDefinition viewDef = new HtmlViewDefinition();
viewDef.RowTemplate.Rows.Add(new RowDefinition());
viewDef.RowTemplate.Rows.Add(new RowDefinition());
viewDef.RowTemplate.Rows.Add(new RowDefinition());
viewDef.RowTemplate.Rows[0].Cells.Add(new CellDefinition("Photo", 0, 1, 3));
viewDef.RowTemplate.Rows[0].Cells.Add(new CellDefinition("FirstName", 0, 1, 1));
viewDef.RowTemplate.Rows[0].Cells.Add(new CellDefinition("BirthDate", 0, 2, 1));
viewDef.RowTemplate.Rows[1].Cells.Add(new CellDefinition("Title", 0, 3, 1));
viewDef.RowTemplate.Rows[2].Cells.Add(new CellDefinition("Address", 0, 1, 1));
viewDef.RowTemplate.Rows[2].Cells.Add(new CellDefinition("City", 0, 1, 1));
viewDef.RowTemplate.Rows[2].Cells.Add(new CellDefinition("Country", 0, 1, 1));
template.ViewDefinition = viewDef;
}
void LoadPerformanceTable()
{
Random r = new Random();
DataTable chartTable = new DataTable();
chartTable.Columns.Add("EmployeeID", typeof(int));
for (int i = 0; i < 12; i++)
{
chartTable.Columns.Add("Month" + (i + 1), typeof(int));
}
foreach (Employee row in dataSource.Employees)
{
DataRow dataRow = chartTable.NewRow();
dataRow["EmployeeID"] = row.EmployeeID;
for (int i = 0; i < 12; i++)
{
dataRow[i + 1] = r.Next(1000) * 10;
}
chartTable.Rows.Add(dataRow);
}
GridViewTemplate template2 = new GridViewTemplate();
template2.Caption = "Performance";
template2.DataSource = chartTable;
template2.AllowRowResize = false;
template2.ShowColumnHeaders = false;
template2.ShowRowHeaderColumn = false;
template2.Columns[0].Width = 600;
for (int i = 1; i < template2.Columns.Count; i++)
{
template2.Columns[i].IsVisible = false;
}
this.radGridView1.Templates.Add(template2);
GridViewRelation relation2 = new GridViewRelation(this.radGridView1.MasterTemplate);
relation2.ChildTemplate = template2;
relation2.ParentColumnNames.Add("EmployeeID");
relation2.ChildColumnNames.Add("EmployeeID");
this.radGridView1.Relations.Add(relation2);
}
Telerik.Charting.ChartSeries GetRowData(GridViewRowInfo row)
{
Telerik.Charting.ChartSeries series = new Telerik.Charting.ChartSeries();
series.Type = ChartSeriesType.Bar;
series.Name = "Sales";
series.Appearance.LabelAppearance.Visible = false;
for (int i = 0; i < 12; ++i)
{
series.Items.Add(new ChartSeriesItem((int)row.Cells[i + 1].Value));
}
return series;
}
protected string GetExampleDefaultTheme()
{
return "ControlDefault";
}
private void timerTick_Tick(object sender, EventArgs e)
{
try
{
eventsSync.WaitOne();
dataSource.Employees[0].FirstName = "test " + count;
count++;
radGridView1.MasterTemplate.Refresh();
eventsSync.Set();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Thanks a lot!
I've been trying to make a grid as a Hierarchy Tabbed GridView (from Q3-2011-SP1 samples) that works with dynamic update on datasource, but I was unsuccessfull. On my grid's data-source I used a BindingSource binding to my object Employees (struct on memory), and simulated through a Timer (500ms) the parameter "FirstName" to be changed on my object. The value updated on my object was showed correctly on the grid cell, but I had a lot of problems with user events like re-ordering/resizing columns or rows.
I used a AutoResetEvent to prevent those conflicts, but my grid still firing two exceptions:
- When I try to re-order columns's headers by drag and drop and new data come at same time there's a failure on CellHeaderElement.ProcessDragDrop() method;
- When I try to use the columns header's Context Menu and new data comes the grid's method Refresh() closes the menu.
I tried to use a VirtualMode grid like Performance Sample but that's not what I need, once my grid must implements filtering\ordering and a nice template with details view.
Here's my code (based on yours, differences are highlighted), I would really appreciate if you guys tell me how to implement a Hierarchy Tabbed GridView without any user events conflicts or context menu closing:
namespace TabbedGridViewSemple
{
public partial class Form1 : Form
{
RadChart chart = new RadChart();
public PlenaDataSet dataSource = new PlenaDataSet();
public OrderDataSet orderSource = new OrderDataSet();
private int count = 0;
public AutoResetEvent eventsSync = new AutoResetEvent(true);
public Form1()
{
InitializeComponent();
}
#region Event handlers
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.radGridView1.BeginUpdate();
//Fill Data Source objects:
dataSource.Add(new Employee() { Address = "507 - Ave. E", BirthDate = new DateTime(1948, 12, 08), City = "Seattle", Country = "USA", EmployeeID = 1, FirstName = "Nancy", LastName = "Davolio", Title = "Sales Representative", Photo = new Bitmap(Properties.Resources.stock_logo) });
dataSource.Add(new Employee() { Address = "908 - Capital", BirthDate = new DateTime(1952, 02,19), City = "Tacoma", Country = "USA", EmployeeID = 2, FirstName = "Andrew", LastName = "Fuller", Title = "Vice President", Photo = new Bitmap(Properties.Resources.stock_logo) });
employeesBindingSource.DataMember = "Employees";
employeesBindingSource.DataSource = dataSource;
ordersBindingSource.DataMember = "Orders";
ordersBindingSource.DataSource = orderSource;
PrepareChartControl();
LoadDetailsTable();
LoadPerformanceTable();
this.radGridView1.UseScrollbarsInHierarchy = true;
this.radGridView1.ReadOnly = true;
radGridView1.MasterTemplate.ChildViewTabsPosition = TabPositions.Bottom;
this.radGridView1.EndUpdate();
}
void radGridView1_ChildViewExpanded(object sender, ChildViewExpandedEventArgs e)
{
eventsSync.Reset();
e.ChildRow.ChildViewInfos[0].ChildRows[0].Height = 152;
e.ChildRow.ChildViewInfos[2].ChildRows[0].Height = 152;
e.ChildRow.Height = 224;
eventsSync.Set();
}
void radGridView1_CellFormatting(object sender, CellFormattingEventArgs e)
{
eventsSync.Reset();
GridViewDataColumn column = e.CellElement.ColumnInfo as GridViewDataColumn;
if (column != null && column.OwnerTemplate.Caption == "Details")
{
if (column.FieldName == "FirstName")
{
e.CellElement.Text = "<html><b>Name:</b> " + e.CellElement.RowInfo.Cells["LastName"].Value + ", " +
e.CellElement.RowInfo.Cells["FirstName"].Value;
}
if (column.FieldName == "BirthDate")
{
e.CellElement.Text = string.Format("<html><b>Birth Date:</b> {0:d}", e.CellElement.RowInfo.Cells["BirthDate"].Value);
}
if (column.FieldName == "Title")
{
e.CellElement.Text = "<html><b>Title:</b> " + e.CellElement.RowInfo.Cells["Title"].Value;
}
if (column.FieldName == "Address")
{
e.CellElement.Text = "<html><b>Address:</b> " + e.CellElement.RowInfo.Cells["Address"].Value;
}
if (e.CellElement is GridImageCellElement)
{
((GridImageCellElement)e.CellElement).ImageLayout = ImageLayout.Zoom;
}
}
if (column != null && column.OwnerTemplate.Caption == "Performance")
{
if (e.CellElement.RowInfo.Tag == null)
{
chart.Series.Clear();
chart.Series.Add(GetRowData((GridViewRowInfo)e.CellElement.RowInfo));
e.CellElement.RowInfo.Tag = chart.GetBitmap();
}
e.CellElement.Image = e.CellElement.RowInfo.Tag as Image;
e.CellElement.DrawBorder = false;
e.CellElement.DrawFill = false;
e.CellElement.Text = "";
e.CellElement.Padding = new Padding(10, 0, 0, 0);
}
eventsSync.Set();
}
void radGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e)
{
eventsSync.Reset();
if (e.CellType == typeof(GridDetailViewCellElement))
{
e.CellElement = new CustomDetailViewCellElement(e.Column, e.Row);
}
eventsSync.Set();
}
#endregion
void PrepareChartControl()
{
chart.Size = new Size(600, 150);
chart.Chart.ChartTitle.Visible = false;
chart.Legend.Visible = false;
chart.Appearance.Border.Visible = false;
chart.Appearance.FillStyle.MainColor = Color.White;
chart.AutoLayout = true;
chart.ChartTitle.Visible = false;
chart.ChartTitle.TextBlock.Text = "";
chart.PlotArea.Appearance.Border.Visible = false;
chart.PlotArea.Appearance.FillStyle.FillType = FillType.Solid;
chart.PlotArea.Appearance.FillStyle.MainColor = Color.Transparent;
chart.PlotArea.Appearance.FillStyle.SecondColor = Color.Transparent;
chart.PlotArea.YAxis.Appearance.CustomFormat = "C0";
chart.PlotArea.YAxis.LabelStep = 2;
chart.PlotArea.XAxis.Appearance.ValueFormat = ChartValueFormat.ShortDate;
chart.PlotArea.XAxis.Appearance.CustomFormat = "dd/MM";
}
void LoadDetailsTable()
{
DataTable table = new DataTable("Details");
table.Columns.Add("EmployeeID", typeof(int));
table.Columns.Add("Photo", typeof(Bitmap));
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("Title", typeof(string));
table.Columns.Add("Address", typeof(string));
table.Columns.Add("City", typeof(string));
table.Columns.Add("BirthDate", typeof(DateTime));
table.Columns.Add("Country", typeof(string));
foreach (Employee row in dataSource.Employees)
{
table.Rows.Add(row.EmployeeID, row.Photo, row.FirstName,
row.LastName, row.Title, row.Address, row.City, row.BirthDate, row.Country);
}
GridViewTemplate template = new GridViewTemplate();
template.Caption = "Details";
template.DataSource = table;
template.AllowRowResize = false;
template.ShowColumnHeaders = false;
template.Columns["Photo"].Width = 125;
template.Columns["City"].Width = 70;
template.Columns["Country"].Width = 70;
template.Columns["FirstName"].DisableHTMLRendering = false;
template.Columns["Title"].DisableHTMLRendering = false;
template.Columns["BirthDate"].DisableHTMLRendering = false;
template.Columns["Address"].Width = 200;
template.Columns["Address"].DisableHTMLRendering = false;
this.radGridView1.Templates.Insert(0, template);
GridViewRelation relation = new GridViewRelation(this.radGridView1.MasterTemplate);
relation.ChildTemplate = template;
relation.ParentColumnNames.Add("EmployeeID");
relation.ChildColumnNames.Add("EmployeeID");
this.radGridView1.Relations.Add(relation);
HtmlViewDefinition viewDef = new HtmlViewDefinition();
viewDef.RowTemplate.Rows.Add(new RowDefinition());
viewDef.RowTemplate.Rows.Add(new RowDefinition());
viewDef.RowTemplate.Rows.Add(new RowDefinition());
viewDef.RowTemplate.Rows[0].Cells.Add(new CellDefinition("Photo", 0, 1, 3));
viewDef.RowTemplate.Rows[0].Cells.Add(new CellDefinition("FirstName", 0, 1, 1));
viewDef.RowTemplate.Rows[0].Cells.Add(new CellDefinition("BirthDate", 0, 2, 1));
viewDef.RowTemplate.Rows[1].Cells.Add(new CellDefinition("Title", 0, 3, 1));
viewDef.RowTemplate.Rows[2].Cells.Add(new CellDefinition("Address", 0, 1, 1));
viewDef.RowTemplate.Rows[2].Cells.Add(new CellDefinition("City", 0, 1, 1));
viewDef.RowTemplate.Rows[2].Cells.Add(new CellDefinition("Country", 0, 1, 1));
template.ViewDefinition = viewDef;
}
void LoadPerformanceTable()
{
Random r = new Random();
DataTable chartTable = new DataTable();
chartTable.Columns.Add("EmployeeID", typeof(int));
for (int i = 0; i < 12; i++)
{
chartTable.Columns.Add("Month" + (i + 1), typeof(int));
}
foreach (Employee row in dataSource.Employees)
{
DataRow dataRow = chartTable.NewRow();
dataRow["EmployeeID"] = row.EmployeeID;
for (int i = 0; i < 12; i++)
{
dataRow[i + 1] = r.Next(1000) * 10;
}
chartTable.Rows.Add(dataRow);
}
GridViewTemplate template2 = new GridViewTemplate();
template2.Caption = "Performance";
template2.DataSource = chartTable;
template2.AllowRowResize = false;
template2.ShowColumnHeaders = false;
template2.ShowRowHeaderColumn = false;
template2.Columns[0].Width = 600;
for (int i = 1; i < template2.Columns.Count; i++)
{
template2.Columns[i].IsVisible = false;
}
this.radGridView1.Templates.Add(template2);
GridViewRelation relation2 = new GridViewRelation(this.radGridView1.MasterTemplate);
relation2.ChildTemplate = template2;
relation2.ParentColumnNames.Add("EmployeeID");
relation2.ChildColumnNames.Add("EmployeeID");
this.radGridView1.Relations.Add(relation2);
}
Telerik.Charting.ChartSeries GetRowData(GridViewRowInfo row)
{
Telerik.Charting.ChartSeries series = new Telerik.Charting.ChartSeries();
series.Type = ChartSeriesType.Bar;
series.Name = "Sales";
series.Appearance.LabelAppearance.Visible = false;
for (int i = 0; i < 12; ++i)
{
series.Items.Add(new ChartSeriesItem((int)row.Cells[i + 1].Value));
}
return series;
}
protected string GetExampleDefaultTheme()
{
return "ControlDefault";
}
private void timerTick_Tick(object sender, EventArgs e)
{
try
{
eventsSync.WaitOne();
dataSource.Employees[0].FirstName = "test " + count;
count++;
radGridView1.MasterTemplate.Refresh();
eventsSync.Set();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Thanks a lot!