August 2004 - Posts
Weird, I thought most developers dedicated to using Microsoft stuff knew about this, but this week I found someone sitting next to me who didn't.
Google can automatically limit your search to Microsoft related links, simply by using this link: http://www.google.com/microsoft. If you need to find something related to Microsoft specific stuff, use this link. It saves you from having to browse too many pages containing all that yucky Java or, heaven forbid, Oracle stuff :-)
If you already knew about this, forgive me for blogging this. Just trying to be helpfull.
In my current project we use type DataSets as a source for the reports we build using Crystal Reports for VS.Net. How this works can be found in the Crystal Reports knowledge base, and more specific in this document.
One of the challenges there was to assign DataSets to the reports once it was created. Based on documentation from Business Objects, the following generic code assigns a DataSet to the ReportDocument and it's subreports.
void AssignDataSet(ReportDocument oReport, DataSet dsData)
{ DataSet dsNew = dsData.Copy();
// Remove primary key info. CR9 does not appreciate this information!!!
foreach (DataTable dataTable in dsNew.Tables)
{ foreach (DataColumn dataCol in dataTable.PrimaryKey)
{ dataCol.AutoIncrement = false;
}
dataTable.PrimaryKey = null;
}
// Now assign the dataset to all tables in the main report
foreach (CrystalDecisions.CrystalReports.Engine.Table oTable in oReport.Database.Tables)
{ oTable.SetDataSource(dsNew);
}
// Now loop through all the sections and its objects to do the same for the subreports
foreach (CrystalDecisions.CrystalReports.Engine.Section crSection in oReport.ReportDefinition.Sections)
{ // In each section we need to loop through all the reporting objects
foreach (CrystalDecisions.CrystalReports.Engine.ReportObject crObject in crSection.ReportObjects)
{ if (crObject.Kind == ReportObjectKind.SubreportObject)
{ SubreportObject crSubReport = (SubreportObject)crObject;
ReportDocument crSubDoc = crSubReport.OpenSubreport(crSubReport.SubreportName);
foreach (CrystalDecisions.CrystalReports.Engine.Table oTable in crSubDoc.Database.Tables)
{ oTable.SetDataSource(dsNew);
}
}
}
}
}
I decided to start posting code samples to help other developers. The first postings will be about DataGrid. The samples are used in the project I'm working on at this moment.
Where in my grid did the user click?
When you want to use the DoubleClick event to start some action on the selected item in the grid, you need to know if the user clicked on the header row, or on a cell containing data. You can use the following code to do that:
bool CellClicked(DataGrid dgGrid)
{
System.Drawing.Point pt = dgGrid.PointToClient(Cursor.Position);
DataGrid.HitTestInfo hti = dgGrid.HitTest(pt);
return (hti.Type == DataGrid.HitTestType.Cell) ;
}
Which data row was selected?
When the user selected a row, you need some way to find the exact row in the datasource. When sorting is now allowed in your grid, you can use the CurrentRowIndex property on the grid. But when sorting is allowed, this method is unreliable. The following code reliably returns the current data row in the grid:
DataRow SelectedRow(DataGrid dgGrid)
{
if (dgGrid.DataSource != null)
{
BindingManagerBase bm = dgGrid.BindingContext[dgGrid.DataSource, dgGrid.DataMember];
if (bm.Count > 0)
{
return ((DataRowView)bm.Current).Row;
}
}
return null;
}
In the C# project I'm doing now, I needed to know whether on string value contained a number or a date. I used a procedure such as this one, which works:
private bool IsNumeric(object value)
{
bool result = false;
try
{
int i = Convert.ToInt32(value);
result = true;
}
catch
{
// Ignore errors
}
return result;
}
And this works, obviously. But browsing the web, I found that some people (like Duncan MacKenzie) suggested using the Visual Basic Runtime in your C# project. Made curious by this I tried it myself and it works brilliantly. I can now use code that is shipped in the .Net Framework to do my testing. To do this yourself, simply follow these three steps:
- Add a reference to Microsoft Visual Basic .Net Runtime.
- Add Using Microsoft.VisualBasic; to the top of your code.
- Use Information.IsNumeric or Information.IsDate to check if your value contains a number or a date.
I'm working on a Windows Forms application at the moment and use the internet as a valuable source of information on various windows forms topics. This morning I was looking for a way to retrieve the datarow in a dataset bound to a datagrid after the grid had been sorted. I found the answer at George Shepherd's Windows Forms FAQ and just had to share that link.
George has combined FAQ from various news groups and placed them in various categories. Just have a look. I've included it in my links :-)