My chart series are really near by each other and this is a problem. I don't know why they are grouped, they look like : http://i39.tinypic.com/wks007.png or http://blogs.msdn.com/blogfiles/alexgor/WindowsLiveWriter/DataBindingMSChartcontrol_10712/image_2.png, but must be separate :(
I want to have each bar with his own name without grouping.
Like on second image, Andrew has 5 Columns near by each other with one title: "Andrew", but I want to have them separately)
How I can do this?
I use the MS chart library
P.S. excuse me for my english :)
My code example:
var table = new DataTable();
s = chart1.Series.Add("Ser1");
s.XValueMember = "Col1";
s.YValueMembers = "Col1_Count";
s = chart1.Series.Add("Ser2");
s.XValueMember = "Col2";
s.YValueMembers = "Col2_Count";
s = chart1.Series.Add("Ser3");
s.XValueMember = "Col3";
s.YValueMembers = "Col3_Count";
table.Columns.Add("Col1", typeof(string));
table.Columns.Add("Col1_Count", typeof(int));
table.Columns.Add("Col2", typeof(string));
table.Columns.Add("Col2_Count", typeof(int));
table.Columns.Add("Col3", typeof(string));
table.Columns.Add("Col3_Count", typeof(int));
Then i execute SqlCommand SELECT and add rows to table and then
chart1.DataBind();
firstly, be sure you put the Charttype as Column in chart control like ChartType="Column",
then, the XValueMember should be the same column, and Bindpoints to series with seperate dataview, like
DataView sDt1 = table .DefaultView.ToTable(true, new[] { "Column_Identifier", "RecordCount" }).DefaultView;
Series[0].Points.DataBindXY(sDt1, "Column_Identifier", sDt1, "RecordCount");
Related
Snippet of the excel table
As can be seen in the Width column, there are some irregular values like "H:15 ,T:5, W:8.5"
For cells like 59cmand 18.50cm I can just remove the cm when reading into the datagrid so that's fine
When reading the excel table into the datagridview, I set the datagridview column for "Width" as double
Snippet of my working code
bomTable = new DataTable("BomTable");
bomTable.Columns.Add("Description", typeof(string));
bomTable.Columns.Add("Vendor", typeof(string));
bomTable.Columns.Add("PartName", typeof(string));
bomTable.Columns.Add("Weight", typeof(double));
bomTable.Columns.Add("WeightUnit", typeof(string));
bomTable.Columns.Add("Width", typeof(double)); //set as double
bomTable.Columns.Add("Width Unit", typeof(string));
Naturally, I cannot assign those irregular values into the Width Column as it is, so is it possible to change its datatype based on a condition? Like for example
Example Code
if (excelRange.Cells[fabricHeaderRow + 1, j].Value2.Contains("H") ||
excelRange.Cells[fabricHeaderRow + 1, j].Value2.Contains("T") ||
excelRange.Cells[fabricHeaderRow + 1, j].Value2.Contains("W"))
{
bomTable.Columns["Width"].DataType = typeof(string);
}
If there's any other workaround, I'd welcome them too
so my problem is that I want to display a table inside another table in WPF.
I use a DataTable in order to display some data and there is one column, in which I need to display another DataTable. I set AutoGenerateColumns="True". For a little testing, this is what I wrote (well, it works as expected):
var curDataTable = new DataTable();
curDataTable.Columns.Add("name" , typeof(string));
curDataTable.Columns.Add("number", typeof(int));
DataRow curRowData = curDataTable.NewRow();
curRowData[0] = "jones";
curRowData[1] = 90;
curDataTable.Rows.Add(curRowData);
Now, let's say I already have a filled DataTable _dataTable. I now want to display this _dataTable in my second column. This is what i would expect to work, but what does not work:
var curDataTable = new DataTable();
curDataTable.Columns.Add("name" , typeof(string));
curDataTable.Columns.Add("table", typeof(DataTable));
DataRow curRowData = curDataTable.NewRow();
curRowData[0] = "jones";
curRowData[1] = _dataTable;
curDataTable.Rows.Add(curRowData);
Has anyone an idea how to fix this?
Using nested DataTables won't work.
What you should do is to replace the outer DataTable with a custom type and bind to a custom collection property of this type in a DataGridTemplateColumn.
I don't think that nested DataTables are possible...
What you can do is create new column in '_datatable' with the name of "name"
_datatable.Columns.Add("name" , typeof(string)).SetOrdinal(0);
Using SetOrdinal(0) you can make "name" column first column. Now you maybe able to add new columns to it.
I hope it helps
Question
How can I have column "Days" populate the results of column "Hours" divided by label25.Text?
Code
Below is the code I'm attempting to accomplish this. I'm thinking the issue is within the foreach portion.
dataGridView4.AutoGenerateColumns = false;
DataTable dt2 = new DataTable();
dt2.Columns.Add("Type", typeof(String));
dt2.Columns.Add("Hours", typeof(String));
dt2.Columns.Add("PerDiem", typeof(String));
dt2.Columns.Add("Days", typeof(decimal)).Expression = "[Hours]/" + label25.Text;
DataGridViewComboBoxColumn type = new DataGridViewComboBoxColumn();
var list10 = new List<string>() { "Tom", "Dick", "Harry"};
type.DataSource = list10;
type.HeaderText = "Type";
type.DataPropertyName = "Type";
DataGridViewTextBoxColumn hours = new DataGridViewTextBoxColumn();
hours.HeaderText = "Hours";
hours.DataPropertyName = "Hours";
DataGridViewComboBoxColumn perdiem = new DataGridViewComboBoxColumn();
var list11 = new List<string>() { "YES", "NO"};
perdiem.DataSource = list11;
perdiem.HeaderText = "PerDiem";
perdiem.DataPropertyName = "PerDiem";
DataGridViewTextBoxColumn days = new DataGridViewTextBoxColumn();
days.HeaderText = "Days";
days.DataPropertyName = "Days";
dataGridView4.DataSource = dt2;
dataGridView4.Columns.AddRange(type, hours, perdiem, days);
dataGridView4.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
type.FlatStyle = FlatStyle.Flat;
perdiem.FlatStyle = FlatStyle.Flat;
Any help would be appreciated!! Thank you in advance.
Update
DataTable dt2 = new DataTable();
dt2.Columns.Add("Hours", typeof(decimal));
dt2.Columns.Add("HoursInAWorkingDay", typeof(decimal));
dt2.Columns.Add("Days", typeof(decimal)).Expression = "[Hours]/[HoursInAWorkingDay]";
DataGridViewTextBoxColumn hours = new DataGridViewTextBoxColumn();
hours.HeaderText = "Hours";
hours.DataPropertyName = "Hours";
DataGridViewComboBoxColumn perdiem = new DataGridViewComboBoxColumn hoursinaworkingday = new DataGridViewComboBoxColumn();
var list13 = new List<string>() { "8", "10", "12", "14" };
hoursinaworkingday.DataSource = list13;
hoursinaworkingday.HeaderText = "Work Day";
hoursinaworkingday.DataPropertyName = "Work Day";
DataGridViewTextBoxColumn days = new DataGridViewTextBoxColumn();
days.HeaderText = "Days";
days.DataPropertyName = "Days";
Made the suggested changes and I'm still falling short. Unfortunately the Days column is not populating a value when entering data in Hours and/or Selecting an option from HoursInAWorkDay. Please help. I know we're close.
Change
dt2.Columns.Add("Days", typeof(String));
To
dt2.Columns.Add("Days", typeof(decimal)).Expression = "[Hours]/" + label25.Text;
Also make your Hours column typeof(decimal) and remove the for loop from the bottom of the code
The days column is now read only and autopopulates based on the hours. If you want it to be variable (ie to update if you change label25.Text) you should instead put a column in the datatable for the divisor and bind label25 to it
Other tips:
String is the default type of a column; you don't need to specify it
You could make your life much easier by adding a DataSet object to your project and doing all this in there; it creates strongly typed datatables that are much easier to work with in every way
Please also name your controls and variables properly - renaming a control/naming a var an apt name takes a couple of seconds. Eventually you will rue the day you wrote the code to be full of meaningless names like "datatable 2, list 10, label 25" because it makes it incredibly difficult to maintain; you're going to constantly have to look up what is what..
You do seem to appreciate the notion of naming some things sensibly (you've called your days and hours Columns "days" and "hours" rather than "decimal1" and "decimal2" - extend the notion out to every line of code you write) - it makes it easier for other developers to help you too
Posting this as a separate answer because your edit actually asks a separate question (how to bind up a combo so it properly edits a table column, versus how to make a table column auto calc a value based on two other columns)
This is a complete fixed code, nicely spaced out/arranged and commented so you can look over it and read what it's doing. You could make a new project, double click the blank form it create and replace the Form1_Load code with this. Note that (with the exception of Form1) I've named variables slightly more sensibly than "dt2", "list13" ;):
private void Form1_Load(object sender, EventArgs e)
{
//set up table
DataTable timesheet = new DataTable();
timesheet.Columns.Add("Hours", typeof(decimal));
timesheet.Columns.Add("HoursInAWorkingDay", typeof(decimal));
//Add creates a column and returns it, so we can set the expression on the return value, without needing to dig it out of the column collection again
timesheet.Columns.Add("Days", typeof(decimal)).Expression = "[Hours]/[HoursInAWorkingDay]";
//set up column for Hours - dont really need this, it would autogenerate
DataGridViewTextBoxColumn hours = new DataGridViewTextBoxColumn();
hours.HeaderText = "Hours";
hours.DataPropertyName = "Hours";
//set up column for HoursInAWorkingDay
DataGridViewComboBoxColumn hoursinaworkingday = new DataGridViewComboBoxColumn();
//make array of decimal values, then use LINQ to turn them into a list of objects that have a `string Dis` and a `decimal Val` property
//these will be used during binding
var hiawd = new[] { 8m, 10m, 12m, 14m }.Select(s => new { Dis = $"{s:0}h", Val = s }).ToList();
hoursinaworkingday.HeaderText = "Work Day";
hoursinaworkingday.DataPropertyName = "HoursInAWorkingDay"; //the column in dt2 that changing the combo shall edit
hoursinaworkingday.DisplayMember = "Dis"; //show the Dis property in the combo, e.g. the string "8h"
hoursinaworkingday.ValueMember = "Val"; //use the Val property of the item selected (e.g. the decimal 8) when setting the HoursInAWorkingDay
hoursinaworkingday.DataSource = hiawd; //the list of values to use for items in the combo. tip: set datasource last
//it is important to appreciate that the combo connects the datatable to the list. it:
//1. reads the dt row's HoursInAWorkingDay,
//2. finds the read value in the Val property of a list item,
//3. shows that item by the Dis property.
//4. when the user picks a new item the value of the new item's Val
// property is written back to the dt HoursInAWorkingDay column
//set up column for Days - dont really need this, it would autogenerate
DataGridViewTextBoxColumn days = new DataGridViewTextBoxColumn();
days.HeaderText = "Days";
days.DataPropertyName = "Days";
var dgv = new DataGridView();
dgv.Columns.Add(hours);
dgv.Columns.Add(hoursinaworkingday);
dgv.Columns.Add(days);
this.Controls.Add(dgv);
dgv.DataSource = timesheet;
dgv.Dock = DockStyle.Fill;
}
I have two DataTables like
DataTable1(With default values)-
Tag |Alias|Value |Type
abc |"" |default|default
xyz |"" |default|default
DataTable2(With actual values)-
Tag |Alias |Value |Type
abc |test |12 |Real
Now if I use DataTable.Merge() I get the rows with both default and actual values for tag abc.
I need only the actual values for a particular tag present in 2nd table, if not the default values from 1st table.
How do i do this?
Just add a primary key constraint to the Tag column before merging.
Example:
var dt1 = new DataTable();
var prime1 = dt1.Columns.Add("Tag", typeof(string));
dt1.Columns.Add("Value", typeof(string));
dt1.Rows.Add(new object[]{"abc", "default"});
dt1.Rows.Add(new object[]{"xyz", "default"});
dt1.PrimaryKey = new DataColumn[]{ prime1 };
var dt2 = new DataTable();
var prime2 = dt2.Columns.Add("Tag", typeof(string));
dt2.Columns.Add("Value", typeof(string));
dt2.Rows.Add(new object[]{"abc", "12"});
dt2.PrimaryKey = new DataColumn[]{ prime2 };
dt1.Merge(dt2);
dt1 now looks like:
I am trying to add column wise data in C#, for e.g.
I have four columns in datatable i.e. No, productoriginal, productmedium, productmedium and productlarge.
first i want to fill ABC then i want to No then Product then productoriginal then productmedium and productlarge
below is my code
DataTable dt = new DataTable();
dt.Columns.Add("No", typeof(Int));
dt.Columns.Add("productoriginal", typeof(string));
dt.Columns.Add("productmedium", typeof(string));
dt.Columns.Add("productlarge", typeof(string));
how do i proceed further ?
If you're looking to add rows to the DataTable, there is a good example on MSDN, but the basics of it is this:
DataRow row = dt.NewRow();
row["No"] = "Value for No here";
row["productoriginal"] = "Value for productoriginal here";
dt.Rows.Add(row);
Take a look into MSDN here.
As mentioned, this is just an example, I'm sure you can amend it as you need to.