I'm having the most crazy issue ever I have one tabcontrol where I add a tabpage then create a datagridview filling it with a query as datasource and make some visual changes on it and then make the same thing for another tabpage.
I run the code and somehow I get the data I want showing in the gridviews everything fine except the visual changes in the second one. I go debugging and end up finding out that the visual changes aren't happening because technically the query return the second datagridview gets as datasource is = {} so it has no rows to make visual changes on. but the data is showing on the datagridview anyway.
I tried changing the order of the datagridviews and it was the very same issue, so I think it's something about the order the code is but I don't understand what nor where exactly.
I'm working on Visual Studio 2012 in C#, accessing the data of a Access 2010 file. And here is the code in question:
///Tabela por calibrar
DataTable tabelaEqui = null;
tabelaEqui = calibracaoBL.planoCalibracaoAtualCalibradosServico(DateTime.Now.Year, servico);
DataGridView gridPorCalibrar = new DataGridView();
gridPorCalibrar.DataSource = tabelaEqui;
tabControl1.TabPages.Add(cbServico.Text + " - Por Calibrar");
tabControl1.TabPages[0].Controls.Add(gridPorCalibrar);
gridPorCalibrar.Dock = DockStyle.Fill;
gridPorCalibrar.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
gridPorCalibrar.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells;
for (int i = 0; i < gridPorCalibrar.Rows.Count - 1; i++)
{
for (int j = 5; j < gridPorCalibrar.Rows[i].Cells.Count; j++)
{
string s = gridPorCalibrar.Rows[i].Cells[j].Value.ToString();
Boolean b = !s.Equals("");
if (b)
{
gridPorCalibrar.Rows[i].Cells[j].Style.BackColor = Color.Green;
}
}
}
mudarCabeçalho(gridPorCalibrar);
///Tabela Calibrados
DataTable dt = null;
dt = calibracaoBL.planoCalibracaoAnosAnterioresServico(DateTime.Now.Year, servico);
DataGridView gridCalibrados = new DataGridView(); // here I got check and dt = {}
gridCalibrados.DataSource = dt;
tabControl1.TabPages.Add(cbServico.Text + " - Calibrados");
tabControl1.TabPages[1].Controls.Add(gridCalibrados);
gridCalibrados.Dock = DockStyle.Fill;
gridCalibrados.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
gridCalibrados.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells;
for (int i = 0; i < gridCalibrados.Rows.Count - 1; i++)
{
for (int j = 5; j < gridCalibrados.Rows[i].Cells.Count; j++)
{
string s = gridCalibrados.Rows[i].Cells[j].Value.ToString();
Boolean b = !s.Equals("");
if (b)
{
gridCalibrados.Rows[i].Cells[j].Style.BackColor = Color.Green;
}
}
}
mudarCabeçalho(gridCalibrados);
Here is the first one:
Here is the second one:
UPDATE in response to #varocarbas :
I'm checking the datasource is blank in two points.
Point one:
dt = calibracaoBL.planoCalibracaoAnosAnterioresServico(DateTime.Now.Year, servico); // that method that runs a query returns {}. But the query itself is not the issue since it works just fine, it's working perfectly when I try it elsewhere.
Point two:
DataTable dt = null;
dt = calibracaoBL.planoCalibracaoAnosAnterioresServico(DateTime.Now.Year, servico);
DataGridView gridCalibrados = new DataGridView(); // here I go check the dt variable and shows dt={}
The code goes into the for (int i = 0; i < gridCalibrados.Rows.Count - 1; i++) but since gridCalibrados.Rows.Count = 0 it skips the loop.
Here is the method mudarCabeçalho
public void mudarCabeçalho(DataGridView grid)
{
for (int i = 5; i < grid.ColumnCount; i++)
{
string[] s = grid.Columns[i].HeaderText.Split('-');
switch (s[1])
{
case "01":
grid.Columns[i].HeaderText = "Jan";
break;
case "02":
grid.Columns[i].HeaderText = "Fev";
break;
case "03":
grid.Columns[i].HeaderText = "Mar";
break;
case "04":
grid.Columns[i].HeaderText = "Abr";
break;
case "05":
grid.Columns[i].HeaderText = "Mai";
break;
case "06":
grid.Columns[i].HeaderText = "Jum";
break;
case "07":
grid.Columns[i].HeaderText = "Jul";
break;
case "08":
grid.Columns[i].HeaderText = "Ago";
break;
case "09":
grid.Columns[i].HeaderText = "Set";
break;
case "10":
grid.Columns[i].HeaderText = "Out";
break;
case "11":
grid.Columns[i].HeaderText = "Nov";
break;
case "12":
grid.Columns[i].HeaderText = "Dez";
break;
}
}
}
Related
I would like to display four images at the same time and upon form load the images switch places. Currently, images will appear in different numbers, for example: 1 image will appear or 2 images, etc up 4. I also want to ensure that no duplicates will appear.
Code from Form1_Load:
PictureBox[] boxes = new PictureBox[4];
boxes[0] = pictureBox0;
boxes[1] = pictureBox1;
boxes[2] = pictureBox2;
boxes[3] = pictureBox3;
for (int i = 0; i < boxes.Length; i++)
{
int switcher = r.Next(0, 5);
switch (switcher)
{
case 0:
{ boxes[i].Image = Properties.Resources.dog0; } break;
case 1:
{ boxes[i].Image = Properties.Resources.dog1; } break;
case 2:
{ boxes[i].Image = Properties.Resources.dog2; } break;
case 3:
{ boxes[i].Image = Properties.Resources.dog3; } break;
}
}
Two examples given above as to what currently happens.
Update - Working
The program now moves images around upon Load and there are no duplicates :)
List<Bitmap> resources = new List<Bitmap>();
resources.Add(Properties.Resources.dog0);
resources.Add(Properties.Resources.dog1);
resources.Add(Properties.Resources.dog2);
resources.Add(Properties.Resources.dog3);
resources = resources.OrderBy(a => Guid.NewGuid()).ToList();
for (int i = 0; i < resources.Count; i++)
{
pictureBox0.Image = resources[0];
pictureBox1.Image = resources[1];
pictureBox2.Image = resources[2];
pictureBox3.Image = resources[3];
}
Two example given above showing what happens now that it works.
The implementation is quite simple. Firstly, you need to shuffle the array and then iterate through it. Fisher–Yates shuffle.
Create a method ShuffleImages as below:
public void ShuffleImages(PictureBox[] img)
{
Random r = new Random();
for (int i = 0; i < img.Length - 1; i++)
{
int j = r.Next(i, img.Length);
PictureBox temp = img[j];
img[j] = img[i];
img[i] = temp;
}
}
and call the method in your Form1_Load event:
private void Form1_Load(object sender, EventArgs e)
{
PictureBox[] boxes = new PictureBox[4];
boxes[0] = pictureBox0;
boxes[1] = pictureBox1;
boxes[2] = pictureBox2;
boxes[3] = pictureBox3;
ShuffleImages(boxes); //call the method
for (int i = 0; i <= 3; i++)
{
switch (i)
{
case 0:
{ boxes[i].Image = Properties.Resources.dog0; }
break;
case 1:
{ boxes[i].Image = Properties.Resources.dog1; }
break;
case 2:
{ boxes[i].Image = Properties.Resources.dog2; }
break;
case 3:
{ boxes[i].Image = Properties.Resources.dog3; }
break;
}
}
}
As M.kazem Ahkhary points out you need to shuffle the images:
List<Bitmap> resources = new List<Bitmap>();
resources.Add(Properties.Resources.dog0);
resources.Add(Properties.Resources.dog1);
resources.Add(Properties.Resources.dog2);
resources.Add(Properties.Resources.dog3);
resources = resources.OrderBy(a => Guid.NewGuid()).ToList(); // Dirty but effective shuffle method
pictureBox0.Image = resources[0];
pictureBox1.Image = resources[1];
pictureBox2.Image = resources[2];
pictureBox3.Image = resources[3];
I have a function that build chart according to selected time range.
The onClick function determinate stored procedure and data source parameters, make makes DataBind() and calls to showChartSum() function
Stored procidure output in case of week range
Need to set d_date as AxisX and the other values as AxisY
Code:
public void showChartSum()
{
DataTable dt_data;
DataView dv_data;
string error_message;
int range_id;
chart_sum.Visible = true;
chart_avg.Visible = false;
range_id = int.Parse(rbl_display02.SelectedValue);
dv_data = (DataView)sds_report.Select(new DataSourceSelectArguments());
dt_data = dv_data.ToTable("DTData", false, "d_date", "tip", "deposit", "compensation", "salary");
if (dt_data.Rows.Count > 0)
{
dt_data = validateMaxChartInput(dt_data);
chart_sum.DataSource = dt_data;
chart_sum.Series["series_tip"].XValueMember = "d_date";
chart_sum.Series["series_tip"].YValueMembers = "tip";
chart_sum.Series["series_deposit"].XValueMember = "d_date";
chart_sum.Series["series_deposit"].YValueMembers = "deposit";
chart_sum.Series["series_compensation"].XValueMember = "d_date";
chart_sum.Series["series_compensation"].YValueMembers = "compensation";
chart_sum.Series["series_compensation"].Color = Color.Red;
chart_sum.Series["series_salary"].XValueMember = "d_date";
chart_sum.Series["series_salary"].YValueMembers = "salary";
chart_sum.Series["series_salary"].Color = Color.SaddleBrown;
//chart_sum.ChartAreas[0].AxisX.Interval = 1;
switch (range_id)
{
case 1:
//chart_sum.ChartAreas[0].AxisX.LabelStyle.Format = "dd/M/yyyy";
chart_sum.ChartAreas[0].AxisY.Interval = 500;
break;
case 2:
//chart_sum.ChartAreas[0].AxisX.LabelStyle.Format = "M/yyyy";
chart_sum.ChartAreas[0].AxisY.Interval = 2000;
break;
case 3:
//chart_sum.ChartAreas[0].AxisX.LabelStyle.Format = "yyyy";
chart_sum.ChartAreas[0].AxisY.Interval = 4000;
break;
}
chart_sum.ChartAreas[0].AxisX.LabelStyle.Angle = 90;
chart_sum.DataBind();
}
else
{
error_message = "הנתונים עבור הטווח הנבחר לא קיימים במערכת";
this.Page.Form.Controls.Add(fn.createCustomMessage(error_message));
pnl_chart.Visible = false;
}
}
The date values are not based on data source, its auto generated according to specified interval.
Chart image
When i comment the interval as sagested by TaW, I get the following output in case of week (fine except of leading and closing labels)
In case of month the labels somehow generated with two weeks interval
Please advise how to display date on chart AxisX as it appear in DataSource and not auto-generated values.
I'm trying to fill in a telerik radDataGridView (the same problem happens with a normal dataGridView as well).
one of the columns in my db table is named [updateType].
the 'type' is described in an enum:
public enum TypeEnum
{
INSERT = 0,
UPDATE_OR_INSERT = 1,
UPDATE = 2,
DELETE_OR_INSERT = 3
};
i'm filling the dataGridView (dgv) in the Load event:
private void Form1_Load(object sender, EventArgs e)
{
this.table1TableAdapter.Fill(this.tempdbDataSet.Table1);
for (int i = 0; i < dgv.RowCount; i++)
{
switch ((int)dgv.Rows[i].Cells[2].Value)
{
case (int)TypeEnum.INSERT:
dgv.Rows[i].Cells[2].Value = "INSERT";
break;
case (int)TypeEnum.UPDATE_OR_INSERT:
dgv.Rows[i].Cells[2].Value = "UPDATE/INSERT";
break;
case (int)TypeEnum.UPDATE:
dgv.Rows[i].Cells[2].Value = "UPDATE";
break;
case (int)TypeEnum.DELETE_OR_INSERT:
dgv.Rows[i].Cells[2].Value = "INSERT/DELETE";
break;
default:
break;
}
}
}
but it fails, when trying to fill in a string value to an int typed gridview cell,
throwing an exception Input string was not in a correct format.
thanks to anyone who can solve this.
Try
switch ((int)dgv.Rows[i].Cells[2].Value)
{
case (int)TableUpdateModeEnum.INSERT:
dgv.Rows[i].Cells[2].Value = (int)TypeEnum.INSERT;
break;
...
...
}
I've solved my problem in a different way.
instead of filling the datagridview with a table adapter,
i've built it step by step.
for example:
//---
for (int i = 0; i < dataset.Tables[0].Rows.Count; i++)
dgv.Rows.Add(dataset.Tables[0].Rows[i].ItemArray[0].ToString(),
dataset.Tables[0].Rows[i].ItemArray[1].ToString(),
GetEnumString((int)dataset.Tables[0].Rows[i].ItemArray[2]));
//---
private string GetEnumString(int n)
{
switch (n)
{
case (int)TypeEnum.INSERT:
return "INSERT";
case (int)TypeEnum.UPDATE:
return "UPDATE";
case (int)TypeEnum.UPDATE_OR_INSERT:
return "UPDATE/INSERT";
case (int)TypeEnum.DELETE_OR_INSERT:
return "INSERT/DELETE";
default: return "";
}
}
}
public enum TableUpdateModeEnum
{
INSERT = 0,
UPDATE_OR_INSERT = 1,
UPDATE = 2,
DELETE_OR_INSERT = 3
};
thank you anyway!
I have a menustrip consists of Menu and Tools
in "Menu" i have subMenus like msO1,msO2,msO3......., and on "Tools" i have subMenus like msP1,msP2,msP3.......,
on Form load all the subMenus visible is false..., On button Click user want to select which subMenus he want...,
in the textBox(txtSelect) if user enter 1,3..., he get msO1, msO3.....,
my code is a hardcode..., if i have 20 subMenus means this code is not helpfull anybody have an idea...,
private void btnSelect_Click_1(object sender, EventArgs e)
{
msO1.Visible = false;//msO1 is a submenu
msO2.Visible = false;
msO3.Visible = false;
msP1.Visible = false;
msP2.Visible = false;
msP3.Visible = false;
string word = txtSelect.Text;
string[] splt = word.Split(',');
int[] arrayItms = new int[splt.Length];
for (int x = 0; x < splt.Length; x++)
{
arrayItms[x]=Convert.ToInt32(splt[x].ToString());
if (splt.Length > 0)
{
switch (arrayItms[x])
{
case 1:
msO1.Visible = true; break;
case 2:
msO2.Visible = true; break;
case 3:
msO3.Visible = true; break;
case 4:
msP1.Visible = true; break;
case 5:
msP2.Visible = true; break;
case 6:
msP3.Visible = true; break;
}
}
}
}
Create an array of your MenuStrip
MenuStrip[] mstrip = new MenuStrip[]
{
msO1,msO2, msO3, msP1, msP2, msP3 // add other menus here when needed
};
now you could work on the array as a Whole to make visible or not your menus
for(int x = 0; x < menus.Length; x++)
mstrip[x].Visible = false;
and your code could be simplified with
for (int x = 0; x < splt.Length; x++)
{
int menuIndex;
if(Int32.TryParse(splt[x], out menuIndex))
{
menuIndex--;
if(menuIndex >= 0 && menuIndex < mstrip.Length)
mstrip[menuIndex].Visible = true;
}
}
Remember, arrays indexes start at zero (while your user will probably start counting a 1).
You could use something like this
string word = txtSelect.Text;
string[] splt = word.Split(',');
for (int x = 0; x < splt.Length; x++)
{
Control myControl1 = FindControl("ms" + splt[x]);
if ( myControl1 != null )
(ToolStripMenuItem)myControl1.Visible = true;
}
Untested but this should get you half way there I hope.
Loop through each ToolStripMenuItem control in the menu strip items and set them to visible.
You can add further conditions inside the loop to define which of the menu items should be made visible based on the users choice..
foreach (ToolStripMenuItem mi in menuStrip1.Items)
{
mi.Visible = true;
}
I'm geting a StackOverflowException. Somehow, posting here seemed appropriate.
I'm using Windows Forms in a C# application. This application is intended to run on Linux, FreeBSD and Mac-OS, so I can't use WPF, so please don't suggest it.
My guess is that I'm missing a nuance of WinForms, but I cant seem to figure out what.
The ComboBox is generated by the GUI form builder in VS 2010.
The specific lines of code that are throwing the error are here:
if(cur_num_is_valid)
{
cbx_material_num.Text = num;
}
else
{
num = "0";
//I only have one of the following two at a time. Both overflow
cbx_material_num.SelectedIndex = 0;
cbx_material_num.Text = "0";
}
Since the code is somewhat complex, here's the whole function code. 'cbx_' indicates a combo box. 'txtb_' is a text box.
private void cbx_material_numobj_SelectedIndexChanged(object sender, EventArgs e)
{
string obj = cbx_material_obj.Text;
string num = cbx_material_num.Text;
int selnum = 0;
int n = 0;
//do we need to recreate the numbers array?
bool cur_num_is_valid = false;
cbx_material_num.Items.Clear();
if(obj != lastobj)
{
n = m_demo.get_object_modifiers(obj);
for(int i = 0; i <= n; i++)
{
string s = i.ToString();
if(s == num && i < n) cur_num_is_valid = true;
cbx_material_num.Items.Add(s);
}
}
if(cur_num_is_valid)
{
cbx_material_num.Text = num;
}
else
{
num = "0";
//Overflow here:
cbx_material_num.SelectedIndex = 0;
}
try
{
selnum = int.Parse(num);
}
catch(Exception)
{
MessageBox.Show("Error, second select menu after 'object modifiers' must be a number, not '"+num+"'.");
cbx_material_num.Text="0";
return;
}
if(selnum >= n)
{
txtb_material_param1.Text = "0";
txtb_material_param2.Text = "0";
txtb_material_param3.Text = "0";
txtb_material_param4.Text = "0";
}
else
{
MaterialFace face;
MaterialParameter parameter;
int typeid;
object paramdata;
m_demo.get_object_modifiers_material(obj, selnum, out face, out parameter, out typeid, out paramdata);
cbx_material_face.Text = face.ToString();
cbx_material_paramtype.Text = parameter.ToString();
switch(typeid)
{
case 0:
txtb_material_param1.Text = ((float)paramdata).ToString();
cbx_material_datatype.Text = "float";
goto case -1;
case 1:
float[] parsf = ((float[])paramdata);
txtb_material_param1.Text = parsf[0].ToString();
txtb_material_param2.Text = parsf[1].ToString();
txtb_material_param3.Text = parsf[2].ToString();
txtb_material_param4.Text = parsf[3].ToString();
cbx_material_datatype.Text = "float[]";
break;
case 2:
txtb_material_param1.Text = ((int)paramdata).ToString();
cbx_material_datatype.Text = "int";
goto case -1;
case 3:
int[] parsi = ((int[])paramdata);
txtb_material_param1.Text = parsi[0].ToString();
txtb_material_param2.Text = parsi[1].ToString();
txtb_material_param3.Text = parsi[2].ToString();
txtb_material_param4.Text = parsi[3].ToString();
cbx_material_datatype.Text = "int[]";
break;
case -1: //can't actuall be returned, used to 'blank' the last three as '0'
txtb_material_param2.Text = "0";
txtb_material_param2.Text = "0";
txtb_material_param3.Text = "0";
break;
case 4:
OpenTK.Graphics.Color4 paramc = ((OpenTK.Graphics.Color4)paramdata);
txtb_material_param1.Text = paramc.R.ToString();
txtb_material_param2.Text = paramc.G.ToString();
txtb_material_param3.Text = paramc.B.ToString();
txtb_material_param4.Text = paramc.A.ToString();
cbx_material_datatype.Text = "Color4";
break;
default: //5
Vector4 paramv = ((Vector4)paramdata);
txtb_material_param1.Text = paramv.X.ToString();
txtb_material_param2.Text = paramv.Y.ToString();
txtb_material_param3.Text = paramv.Z.ToString();
txtb_material_param4.Text = paramv.W.ToString();
cbx_material_datatype.Text = "Vector4";
break;
}
}
}
You need to check that the SelectedIndex isn't already 0 before you try to set it:
if (cbx_material_num.SelectedIndex != 0){
cbx_material_num.SelectedIndex = 0;
}
Otherwise you're re-firing the event every time through.
I think that whenever you set this cbx_material_num.SelectedIndex = 0; within the EventHandler you invoke your
cbx_material_numobj_SelectedIndexChanged(object sender, EventArgs e)
Each call invokes another eventHandler so the stack fills up after some time.
Basically, the fact that it is called SelectedIndexChanged doesn't mean that the value has to be different from the previous one but that the value is set through its setter.