|
Hi,
I want to check for existing open forms and if the desired form was not open, open it.
The problem is that my code gives runtime error:
System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute.'
this error occurs in this part of the code:
foreach (Form frm in fc)
How can I fix this?
my code:
FormCollection fc = Application.OpenForms;
foreach (Form frm in fc)
{
if (frm.Name == "Chart")
{
MessageBox.Show("The form is open","error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
else
{
Chart myCharts = new Chart();
myCharts.Show();
}
}
modified 25-Mar-21 5:35am.
|
|
|
|
|
You don't show the code of your loop body, but from the error message you are either adding or removing a control / form from the collection fc inside the loop. You can't do that: modifying the source of an iterator while the iterator is in use because if you did, it would not be clear what the next iteration value should be!
You could change to a for loop, but you may need to run it backwards to avoid getting a similar problem in your own code.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I forgot to provide my code. I added it to the main question.
I repeat it again:
FormCollection fc = Application.OpenForms;
foreach (Form frm in fc)
{
if (frm.Name == "Chart")
{
MessageBox.Show("The form is open","error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
else
{
Chart myCharts = new Chart();
myCharts.Show();
}
}
|
|
|
|
|
Yes - and you are adding a form to the collection.
When you call Show, it adds the new form to the Application.OpenForms collection, and since fc is a reference to that collection, you are modifying the collection which you are iterating over it. Worse, you are adding it every time an existing form is not teh one you are looking for!
You can't do that.
The way I'd do it is simpler:
if (!Application.OpenForms.Cast<Form>().Any(frm => frm.Name == "Chart"))
{
... add your new form ...
}
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
NB: In your current code, you will open another instance of the chart form for every non-chart form you have open, regardless of how many instances of the chart form are already open.
Try:
ChartForm myCharts = Application.OpenForms.OfType<Chart>().FirstOrDefault();
if (myCharts == null)
{
myCharts = new Chart();
myCharts.Show();
}
else
{
myCharts.Activate();
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Please help me to create a code for copy a selected gridview row to the same gridview in asp.net c#
|
|
|
|
|
You create a new row; you then copy the selected row to the new row.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
Now now, isn't suggesting problem decomposition a bit unfair? That requires more thought than "cOdEz PlZ!"
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
Slightly off topic:
Thanks for your sig
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
I've been using the quote for a long time (and I'd misremembered it as "Never attribute to malevolence that which can be explained by stupidity.") and had not found out where it had originated.
|
|
|
|
|
Eh, you may well have it right; it's existed in many forms over the years. I think the original went with "incompetence" as well, but I have admittedly picked a version that reflects my own feelings.
At any rate, it's an absolutely essential attitude when working in cybersecurity.
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
Nathan Minier wrote: At any rate, it's an absolutely essential attitude when working in cybersecurity. or when getting edicts from management!
|
|
|
|
|
I am creating a book site for that, I have created dynamic buttons so that if on a particular category is clicked then that row will be fetched from the database and required information will be displayed. Now I want that if the user clicks on any particular book then the data of that book should be displayed in another panel and the current panel should hide.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.UI.HtmlControls;
namespace WebApplication1
{
<pre>
public partial class Genre : System.Web.UI.Page
{
private int num;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);<br />
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "Romance";
Panel2.Visible = false;
con.Open();
String SQL = "Select * from Book_List where Book_category='" + Label1.Text + "'";
SqlDataAdapter da = new SqlDataAdapter(SQL, con);
DataSet ds = new DataSet();
DataTable dt = new DataTable();
da.Fill(ds);
num = ds.Tables[0].Rows.Count;
HtmlGenericControl Book = new HtmlGenericControl("div");
Book.Attributes.Add("class", "books");
Panel1.Controls.Add(Book);
for (int i = 1; i < num; i++)
{
HtmlGenericControl myDiv = new HtmlGenericControl("div");
myDiv.Attributes.Add("class", "myDiv");
ImageButton image = new ImageButton();
image.ImageUrl = ds.Tables[0].Rows[i]["Book_image"].ToString();
image.CssClass = "Img";
image.Click += new ImageClickEventHandler(this.image_Click);
HtmlGenericControl content = new HtmlGenericControl("div");
content.Attributes.Add("class", "content");
Label name = new Label();
name.CssClass = "name";
name.Text = ds.Tables[0].Rows[i]["Book_name"].ToString();
Label cost = new Label();
cost.CssClass = "cost";
cost.Text = "<br/> Rs " + ds.Tables[0].Rows[i]["Book_cost"].ToString();
Button wishlist = new Button();
wishlist.CssClass = "wishlist";
wishlist.Text = "ADD TO WISHLIST";
Book.Controls.Add(myDiv);
myDiv.Controls.Add(image);
myDiv.Controls.Add(content);
content.Controls.Add(name);
content.Controls.Add(cost);
content.Controls.Add(wishlist);
}
}
protected void image_Click(object sender, ImageClickEventArgs e)
{
ImageButton image = sender as ImageButton;
Panel2.Visible = true;
Panel1.Visible = false;
}
</pre>
|
|
|
|
|
Every control in .NET has a Tag property, which is an object so it can store any instance of any class. If you create a class to hold the book information, you could set the Tag of the button to that class instance when you create the Button.
Then in the Click handler you can get the Button instance from the sender parameter, and use that to get the book information from it's Tag.
Then you can do with it what you wish!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Not in a WebForms app.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Member 15084749 wrote: String SQL = "Select * from Book_List where Book_category='" + Label1.Text + "'";
Don't do it like that!
Although this specific case is OK since you're using a constant value, using string concatenation to build a SQL query can and will leave you vulnerable to SQL Injection[^].
NEVER use string concatenation to build a SQL query. ALWAYS use a parameterized query.
const string SQL = "Select * from Book_List where Book_category = @BookCategory";
SqlDataAdapter da = new SqlDataAdapter(SQL, con);
da.SelectCommand.Parameters.AddWithValue("@BookCategory", Label1.Text); Everything you wanted to know about SQL injection (but were afraid to ask) | Troy Hunt[^]
How can I explain SQL injection without technical jargon? | Information Security Stack Exchange[^]
Query Parameterization Cheat Sheet | OWASP[^]
Also, don't store the database connection in a class-level field. Instead, create it where necessary, and wrap it in a using block to ensure that it's always disposed of properly.
private static SqlConnection CreateConnection()
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
}
...
DataSet ds = new DataSet();
using (SqlConnection con = CreateConnection())
{
const string SQL = "Select * from Book_List where Book_category = @BookCategory";
SqlDataAdapter da = new SqlDataAdapter(SQL, con);
da.SelectCommand.Parameters.AddWithValue("@BookCategory", Label1.Text);
da.Fill(ds);
}
DataTable dt = ds.Tables[0];
...
And do yourself a favour and give your controls meaningful IDs, rather than accepting the default values suggested by the Visual Studio designer. Sure, you might remember what Label1 refers to now, but when you come back to your code in three weeks, you'll have forgotten.
As to your question, Page_Load is too late to initialize your dynamic controls. Do it in Page_Init instead.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
ooh, I hope one of the categories is
SQL Injection - how to do it';drop table book_list;' Let me know the URL when it's live
Seriously, parameterise that.
|
|
|
|
|
Hello All,
I am still pretty new to C# and have run into a little issue.
I have program which passes data into Excel and can be used on the same workbook many times. Therefore, I need to check to see if cell 7,1 (for instance) already contains data from a previous pass and if so, move to cell 11,1, do the same test and if that has data, move to cell 15,1 etc. etc. I think I possibly require some sort of Switch statement where we keep falling through until the specified cell is empty and therefore ready to receive data, i.e. look at 7,1 > 11,1 > 15,1 > 19,1 right down to row number 55 (the cell rows increase by multiples of 4) but I am struggling with it.
Can anyone provide the best practice for doing this?
Thanks,
Steve
modified 22-Mar-21 12:44pm.
|
|
|
|
|
The whole thing sounds pretty fragile; and without some "what for", a pointless mental exercise.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
OK Gerry, here is the full scenario.
My program functions inside of AutoCAD and is intended to export some product data to a "Packing List"
which is a spreadsheet in Excel.
This is the workflow:
1. The draughtsman is prompted to make a selection from a number of products (AutoCAD entities) on the drawing which will comprise of the items to be added to the Packing List.
2. He then allocates the selection to a Bundle number, which he is prompted for and defines himself.
3. The program then looks for an excel book with the same name as the drawing file and if it does not exist, creates a new one from a defined template.
4. It then iterates through the selection set and extracts all of the part numbers and builds a string of the numbers to be written out i.e. 1, 2, 3, 4, 5 etc.
5. If we are in a new workbook, the string is written into the first cell at row 7.
6. The workbook is then saved and closed.
7. When this process is finished, the draughtsman can then start over again and make another selection which he then allocates to a different Bundle number.
8. At this point, the program finds the existing workbook and opens it, but now needs to start at the first cell on row 11 as cell 7, 1 already holds data.
This workflow can carry-on upto 13 times, when the last row will be reached.
Hope this is clearer.
Steve
ps I can't see how to include a snapshot of the packing list spread sheet.
|
|
|
|
|
It is a simple loop:
bool found = false;
for (int row = 7; row < 56; row += 4)
{
if (cell[row, 1] is empty
{
found = true;
break:
}
}
if (!found)
{
}
|
|
|
|
|
Hi Richard,
Thanks for your suggestion. I will try this later today and let you know how I get on.
Steve
|
|
|
|
|
Hi Richard,
Thanks for pointing me in the right direction.
I changed your suggestion as below...it works a treat!
for (int row = 7; row < 56; row += 4)
{
if (workSheet.Cells[row, 1] == null || workSheet.Cells[row, 1].Value2 == null || workSheet.Cells[row, 1].Value2.ToString() == "")
{
workSheet.Cells[row, 1] = (string)fillinData.GetValue(0);
workSheet.Cells[row + 1, 18] = (string)fillinData.GetValue(1);
workSheet.Cells[row - 1, 10] = (string)fillinData.GetValue(8);
break;
}
}
Thanks again,
Steve
|
|
|
|
|
|
Greetings!
Does anyone know how an XML (an example is given below) file created in the Mike Hankey`s GRADIATOR
program would be written in C# itself?
Specifically I mean the full definition of brush.
GraphicsPath g = new GraphicsPath();
PathGradientBrush brush = new PathGradientBrush(g);
.
.
.
Thanks in advance, Aleksandar
p.s. https://www.codeproject.com/Articles/20018/Gradients-made-easy
example:
<ShapeObjects>
<ShapeObject>
<Id>28316747</Id>
<Rectangle>200,201,384,384</Rectangle>
<FontFamily>Palatino Linotype</FontFamily>
<FontSize>10</FontSize>
<Text>
</Text>
<Type>Elliptical</Type>
<HasBorder>True</HasBorder>
<BrushName>
</BrushName>
<FillType>pathGradient</FillType>
<Color>Color [A=255, R=255, G=255, B=255]</Color>
<Color1>Color [Black]</Color1>
<Color2>Color [A=255, R=180, G=180, B=180]</Color2>
<LinearAngle>90</LinearAngle>
<CenterPoint>{X=0.5104167, Y=0.5104167}</CenterPoint>
<UseSigmaShape>True</UseSigmaShape>
<UseBlendShape>False</UseBlendShape>
<SurroundColors>Color [A=255,R=0,G=27,B=82]</SurroundColors>
<Focus>0.507451</Focus>
<Scale>0.6080391</Scale>
<Positions>0,1</Positions>
<Factors>0.2,0.8</Factors>
<UseBlend>False</UseBlend>
<UseColorBlend>False</UseColorBlend>
<UseGammaCorrection>False</UseGammaCorrection>
<FocusScale>{X=0.8039216, Y=0.8015845}</FocusScale>
</ShapeObject>
</ShapeObjects>
|
|
|
|
|
If you have a question about the code in an article, post it in the forum at the bottom of that article. That way, the author will be notified and will have a chance to respond to your question.
Mike is still quite active here.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|