Specify multiple values for point tooltip using Chart.DataBindCrossTable() - c#

I'm using a Microsoft chart control and binding a DataTable to it using Chart.DataBindCrossTable One of the parameters is a string called otherFields and you can specify any property associated with a Point in that string:
chart.DataBindCrossTable(table.Rows, "COLUMN1", "COLUMN2", "COLUMN3", "Label=COLUMN4, LegendText=COLUMN1, ToolTip=COLUMN3");
I wan't to specify multiple columns in the ToolTip field, something like:
ToolTip=COLUMN3 = COLUMN4
so that the tool tip for each point would be "COLUMN3 = COLUMN4" where column3 and 4 would be filled in with whatever the values were in those columns/rows for that point.
But when I do this I get an error saying that there wasn't a column called "COLUMN3 = COLUMN4" in the datasource. How can I make this happen?

You could create another calculated column in your datatable to display what you want and bind to that.

Related

Display DataSource from DataGridView in ReportViewer

Following on from an earlier question about dynamic columns in a report viewer, I thought I would at least attempt to get things working.
The output being displayed are columns of mathematical factors, each with their own unique name. These factors (any number from 1 to 10 can be selected) display without issue in my DataGridView control - I generate a DataTable by adding rows/columns as required, and then set the datatable as the Datasource for the DataGridView.
I have added a ReportViewer to my WinForm, and generated a RDLC file. Rather than spend hours trying to figure out how to make it dynamic, my RDLC is set up with 10 columns (as I know there will never be more than this), and the DataSet is assigned to my ReportViewer control. I then use the following code to assign the data to the viewer:
DataTable dt = new DataTable();
var source = this.dgvSelectedElements.DataSource;
while (source is BindingSource)
{
source = ((BindingSource)source).DataSource;
}
var table = source as DataTable;
if (table != null)
{
dt = table;
var reportSource = new ReportDataSource("FactorReport", dt);
this.reportViewer1.Reset();
this.reportViewer1.ProcessingMode = ProcessingMode.Local;
this.reportViewer1.LocalReport.ReportPath = "FactorReport.rdlc";
this.reportViewer1.LocalReport.DataSources.Clear();
this.reportViewer1.LocalReport.DataSources.Add(reportSource);
this.reportViewer1.RefreshReport();
}
So this is how the DataGridview looks:
And then, this is the Reportviewer - note the two 'Rate' and 'Mult' rows appear at the bottom
So whilst it appears to work, I cannot see the values in the grid. Also, when the ages exceed 100, the ages are sorted incorrectly - can sorting be turned off? And on the assumption I can get this to work, is it possible to iterate through the ReportViewer and amend the column captions? A quick google tells me not at run-time?
You should set name of columns in your DataTable which you ceate dynamically as DataSource of DataGridView correctly. They should be Age, Factor1, Factor2, ... , Factor10.
You created the report using those column names. So when you create a DataTable for your grid dynamically, you should set column names same as names you used when creating report.
How can I have same column names?
But you can fix the problem simply by creating a temporary DataTable containing Age, Factor1, ... , Factor10, filled by the original data table. Pass this table to the report and it will work.
How can I have same column titles which is shown in DataGridView?
The solution is column titles as parameters. Create 10 parameters in the report designer and set the title of columns of tablix in report using parameters but don't change name of columns. Those should be Age, Factor1, .... Then when you want to show the report, additional to the temp table which I mentioned above, pass column titles using parameters.
Another Idea
As another idea, you can have the report using exactly the same DataTable which contains all available columns and then when you want to show some columns in report, just pass some parameters to grid which indicates visibility of each column.
Maybe not the best/quickest solution but it works and with some additional changes to the visibility expressions, I'm able to only show the number of columns that have been selected.
I added 10 parameters to my reportviewer named Factor_Name_1 to Factor_Name_10, and checked 'Allow null value' in the properties when creating them. I then wrote some code to add the data for the parameters, storing the existing column names before renaming them to my Factor1, Factor2...Factor10 headings as follows (note I am not worried about in the first 'Age' column):
// loop through the columns to create parameters...
for (int i = 1; i < dt.Columns.Count; i++)
{
// get the name of the column...
string factorName = dt.Columns[i].ColumnName;
// define the new column name...
string colName = string.Format("Factor_Name_{0}", i);
// change the column name now we have stored the real name...
dt.Columns[i].ColumnName = string.Format("Factor{0}", i);
// generate the parameter...
var rparam = new ReportParameter(colName, factorName);
// add it to the parameter set for the control...
this.reportViewer1.LocalReport.SetParameters(new[] { rparam });
}
By re-setting the column names once I've created the associated parameter, the data will then bind correctly. All I had to do then, in my RDLC designer, is to replace the existing headings with the associated parameter values. Then, to hide the columns not selected, I set the visibility expression for the Parameter and Row Textboxes to:
=IIF(ISNOTHING(Parameters!Factor_Name_1.Value),True,False)
....
....
=IIF(ISNOTHING(Parameters!Factor_Name_10.Value),True,False)
Now, if I choose 1 or 10 columns, the viewer displays the correct number of columns and hides those not required. Am now working on repeating the 'age' column (already have the headings repeating) and adding a header/footer at runtime, but I currently have a report that displays the data I need with the correct headings.
Thanks to #Reza Aghaei for getting me on the right track.

Configuring 'AutoGenerateColumns' property of a DataGridView

I have a datagridview configured to autogenerate columns based on my class (using databinding).
It works just fine for all my properties of type string. However, I have a property of an enum type, with a typeconverter to convert it to an image.
I'd like for my Grid's autogeneration of columns to produce a DataGridViewImageColumn instead of a DataGridViewTextBoxColumn.
The only DGV method that seems helpful is columns added. However, you cannot set the column there, only get & modify.
Any Ideas?
as far as i know, the AutoGeneration isn't very configurable
but you can make an alternative auto gen for yourself:
set autogen = false,
register to these events:
OnDataMemberChanged
OnDataSourceChanged
add a single function that will be triggered for both, which will create columns for the dataSource given:
header = column name
column type = according to what you want
data binding = the column name
etc.

.NET Charting Controls: Label values from data source

I know that you can use keywords with labels, but is there any way to use a specific value from my data set as a label? What I would like to do is have a column of my data table contain a custom label string, so that each X-axis value graphed would have a unique label, but it seems there is no way to connect a series to an element from my data source. Is there a workaround to this, or will I just have to manually add labels over the chart?
I believe you are looking for setting a label for your datasource which is different from the columns which derive the X and Y values.In that case you can do this in the following manner
Chart1.Series[0].Points.DataBind(data, "XValue", "YValue",
"ToolTip=mytooltip,Label=LabelColumnName");
Here you can specify the column name against Label which would be used to display the label, in the same fashion you could also set up the tooltip from a different property.
If this is not you are looking out then please update the question with more details.
EDIT
you can set the position of the label using CustomProperties of the series
Chart1.Series[0].CustomProperties = "LabelStyle=Left"; Check this

add a column between two columns of a gridview

I used a datagridview in my winform application.
I load datagrid with a dataset that have 4 columns.
Next I want to add a column between column2 & column3.
How to I do this.
Thanks.
You can use Insert method on DataGridView.Columns collection. For example,
var column = new DataGridViewTextBoxColumn();
// initialize column properties
...
myGridView.Columns.Insert(2, column);
Preferably, this should happen after the data binding.
Using the Visual Studio Designer, you can simply add columns of every kind in the options of the DGV.
You can even set the position of the columns by drag&drop.
If you can't or don't want to use the Designer VinayC told you to do it the code-way.

Array as DataSource of a DataGrid: how to customize columns?

In my Windows Mobile .NET application I have a simple array of object with the data I want to display in my DataGrid. To do this, I simply call:
myDataGrid.DataSource = myArray;
This works, but I have a problem with it: it uses all properties as columns and uses the names of the properties as the column headers. I can't figure out how to customize two things:
Select which subset of properties should be displayed as columns (say I have an ID, Name and Value property, I'd only want to show Name and Value);
Rename the column headers to make more sense (for example if the property is called ID display a column header saying "Number").
Is this possible at all?
As mentioned this is in a Windows Mobile .NET (version 2) application.
You need to set the Datagrid.TableStyles property to customize the layout.
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagrid.tablestyles.aspx
More details on binding to an array of objects here:
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridtablestyle.mappingname(VS.71).aspx
To bind the
System.Windows.Forms.DataGrid to a
strongly typed array of objects, the
object must contain public properties.
To create a DataGridTableStyle that
displays such an array, set the
MappingName property to classname[]
where classname is replaced by the
class name. Also note that the
MappingName property is
case-sensitive.
I don't know if you know the name of the columns in advance? But if it's the case, you can go in the "Edit Columns" of your DataGridView and just create your columns there. In the "Data" Category, change the "DataPropertyName" from "(none)" to the name of the class property. From there you can customize the name, if it's visible, the size, etc. The DataGrid will bind it to your DataSource.
Also, there is a property "DataGridView.AutoGenerateColumns" that you can set to false so you don't have to bind all the properties of your object. I tought that migh help as well.
In this code _im is an object of table and I bind this object with DataGridView dgvItem after binding I change header text of dgvItem as required.
dgvItem.Rows.Clear();
dgvItem.DataSource = _im ;
dgvItem.Columns[2].HeaderText = "Mobile Code";
dgvItem.Columns[3].HeaderText = "Mobile Name";

Categories

Resources