I want to programmatically create a panel and add some pictureBoxes where i select the image through a for loop. I tried lots of ways but the form shows empty.
My code is :
private void draw_pipeline()
{
Panel pnl = new Panel();
pnl.Size = new System.Drawing.Size(1130, 145);
pnl.Location = new Point(380, 260);
pnl.BorderStyle = BorderStyle.FixedSingle;
for (int i =0; i<3; i++)
{
PictureBox pic = new PictureBox();
pic.SizeMode = PictureBoxSizeMode.Zoom;
switch (i)
{
case 0:
{
pic.Location = new Point(3, 15);
pic.Size = new Size(73, 121);
pic.Image = new Bitmap("if.png"); break;
}
case 1:
{
pic.Location = new Point(76, 15);
pic.Size = new Size(73, 121);
pic.Image = new Bitmap("line.png"); break;
}
}
pnl.Controls.Add(pic);
}
}
the result i want to create is illustrated in the picture below, that contains two picture boxes with two images, if.png which is the if-box image and the line.png which is the line image. I repeat the result of my code is that form shows empty!! Any help?
You'll need to add the Panel to the Form at some point, in the same way you're adding PictureBoxes to the Panel:
this.Controls.Add(pnl);
(The this is assuming that your draw_pipeline method belongs to the Form to which you're trying to add the Panel.)
Related
Goal: when the application starts I want to generate a button per each picture in my resources (6 for testing, 128 final build), in side of a TabPage.
Here is where i am at so far:
private void tabPage1_load(object sender, EventArgs e)
{
ResourceSet rs = new ResourceSet("");
IDictionaryEnumerator id = rs.GetEnumerator();
List<Bitmap> CIcons = new List<Bitmap>();
while (id.MoveNext())
{
if (id.Value is Bitmap)
CIcons.Add((Bitmap)id.Value);
}
}
this doesn't seem to do the trick, any suggestions would be greatly appreciated
Edit(addition): the issue is when the application starts I'm not seeing the images listed int "tabPage1".
also yes i do have 6 images added to my "Resource Folder" inside Visual Studios.
Just for future folks i wanted to add the finished working code:
// Button list start
// Credit to Jcl
ResourceSet rs = Properties.Resources.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
IDictionaryEnumerator id = rs.GetEnumerator();
List<Bitmap> CIcons = new List<Bitmap>();
while (id.MoveNext())
{
if (id.Value is Bitmap)
CIcons.Add((Bitmap)id.Value);
}
int yposition = 0;
foreach (var bmp in CIcons)
{
Button button = new Button();
button.Location = new Point(0, yposition);
button.Size = new Size(125, 125);
button.Visible = true;
button.BackgroundImage = bmp;
tabPage1.Controls.Add(button);
yposition += 125;
}
//Button list end
If you want to generate a button, I'd say something like:
private void tabPage1_load(object sender, EventArgs e)
{
ResourceSet rs = new ResourceSet("");
IDictionaryEnumerator id = rs.GetEnumerator();
List<Bitmap> CIcons = new List<Bitmap>();
while (id.MoveNext())
{
if (id.Value is Bitmap)
CIcons.Add((Bitmap)id.Value);
}
// Vertical aligned: i'll let you figure out how to position them
int yposition = 0;
foreach(var bmp in CIcons)
{
var button = new Button();
button.Location = new Point(0, yposition);
button.Size = new Size(50, 20); // for example
button.Visible = true;
button.BackgroundImage = bmp;
tabPage1.Controls.Add(button);
yposition += 20; // height of button
}
}
Update
As noted in the comments (I thought it was example code, but seems it's not), you also need to specify where to get the ResourceSet from. In your case, change:
ResourceSet rs = new ResourceSet("");
for
ResourceSet rs = Properties.Resources.ResourceManager.GetResourceSet(
CultureInfo.CurrentUICulture, true, true);
Code legibility bonus
All this code:
IDictionaryEnumerator id = rs.GetEnumerator();
List<Bitmap> CIcons = new List<Bitmap>();
while (id.MoveNext())
{
if (id.Value is Bitmap)
CIcons.Add((Bitmap)id.Value);
}
Is equivalent to:
List<Bitmap> CIcons = new List<Bitmap>();
foreach(var bmp in rs.OfType<Bitmap>())
CIcons.Add(bmp);
And since you can create a list from an enumerable, you could simply do:
List<Bitmap> CIcons = new List<Bitmap>(rs.OfType<Bitmap>());
But also, since you are not using your bitmap list for anything else than creating the buttons, you could just not define it, and then your whole code becomes:
var rs = Properties.Resources.ResourceManager.GetResourceSet(
CultureInfo.CurrentUICulture, true, true);
int yposition = 0;
foreach (var bmp in rs.OfType<Bitmap>())
{
var button = new Button()
{
Location = new Point(0, yposition),
Size = new Size(125, 125),
Visible = true,
BackgroundImage = bmp,
};
tabPage1.Controls.Add(button);
yposition += 125;
}
This could be further optimized: if I was you, instead of positioning by calculating the pixel location of each component, I'd use a FlowLayoutPanel to arrange the buttons. Usage of the FlowLayoutPanel is way outside the scope of this question though, I'm just mentioning it just in case you want to investigate and google further
I'm supposed to create a magic square in 2D using Windows Forms Application. It should look like this:
However, the user should be able to decide the size of the square (3x3, 5x5, 7x7, etc). I already wrote the code in a Console Application, but I don't know how to add the 2D graphics.
Somebody already asked this question (How do I put my result into a GUI?), and one of the answers was to use DataGridView, but I'm not sure if that's what I'm looking for, since I can't make it look like the picture.
Any ideas or advice?
You can use a TableLayoutPanel and add buttons to panel dynamically.
If you don't need interaction with buttons, you can add Label instead.
Create square dynamically:
public void CreateSquare(int size)
{
//Remove previously created controls and free resources
foreach (Control item in this.Controls)
{
this.Controls.Remove(item);
item.Dispose();
}
//Create TableLayoutPanel
var panel = new TableLayoutPanel();
panel.RowCount = size;
panel.ColumnCount = size;
panel.BackColor = Color.Black;
//Set the equal size for columns and rows
for (int i = 0; i < size; i++)
{
var percent = 100f / (float)size;
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, percent));
panel.RowStyles.Add(new RowStyle(SizeType.Percent, percent));
}
//Add buttons, if you have your desired output in an array
//you can set the text of buttons from your array
for (var i = 0; i < size; i++)
{
for (var j = 0; j < size; j++)
{
var button = new Button();
button.BackColor = Color.Lime;
button.Font = new Font(button.Font.FontFamily, 20, FontStyle.Bold);
button.FlatStyle = FlatStyle.Flat;
//you can set the text of buttons from your array
//For example button.Text = array[i,j].ToString();
button.Text = string.Format("{0}", (i) * size + j + 1);
button.Name = string.Format("Button{0}", button.Text);
button.Dock = DockStyle.Fill;
//If you need interaction with buttons
button.Click += b_Click;
panel.Controls.Add(button, j, i);
}
}
panel.Dock = DockStyle.Fill;
this.Controls.Add(panel);
}
If you need interaction with buttons
void button_Click(object sender, EventArgs e)
{
var button = (Button)sender;
//Instead put your logic here
MessageBox.Show(string.Format("You clicked {0}", button.Text));
}
As an example, you can call
CreateSquare(3);
Screenshot:
You can create a Form and add a TableLayoutPanel with this property
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.BackColor = Color.Gold;
and this is the result
When you create Row and Column, to fit correctly set the percentage in this way:
After this you can add a Button or Label in each square.
I need your help, I'm using this code to generate multiple tabs in a TabControl each containing a PictureBox with a different JPG picture:
foreach (var file in d.GetFiles("*.jpg"))
{
string title = file.Name + (TCFichiers.TabCount + 1).ToString();
TabPage myTabPage = new TabPage(title);
TCFichiers.TabPages.Add(myTabPage);
PictureBox i = new PictureBox();
myTabPage.Controls.Add(i);
}
I want to use a button that will rotate the image in the PictureBox of the selected tab however I can't figure out how to get access to the right PictureBox. How can I access only the picturebox on the selected tab?
Thanks
See this:
PictureBox[] Shapes = new PictureBox[Num_Picbox];
for (int i = 0; i < Num_Picbox; i++)
{
Shapes[i] = new PictureBox();
Shapes[i].Name = "ItemNum_" + i.ToString();
Shapes[i].Location = new Point(label5.Left+1,label5.Top);
Shapes[i].Size = new Size(100, 100);
Shapes[i].BackColor = Color.Black;
Shapes[i].Image = (Bitmap)(e.Data.GetData(DataFormats.Bitmap));
Shapes[i].Visible = true;
this.Controls.Add(Shapes[i]);
}
I've got the following UIActionSheet.
How do I add it to my top navigation bar?
Preferably as the far right button.
var sheet = new UIActionSheet ("");
sheet.AddButton ("Discard Picture");
sheet.AddButton ("Pick New Picture");
sheet.AddButton ("Cancel");
sheet.CancelButtonIndex = 2;
// Dummy buttons to preserve the space for the UIImageView
for (int i = 0; i < 4; i++) {
sheet.AddButton("");
sheet.Subviews[i+4].Alpha = 0; // And of course it's better to hide them
}
var subView = new UIImageView();
subView.ContentMode = UIViewContentMode.ScaleAspectFill;
subView.Frame = new RectangleF(23,185,275,210);
// Late Steve Jobs loved rounded corners. Let's have some respect for him
subView.Layer.CornerRadius = 10;
subView.Layer.MasksToBounds = true;
subView.Layer.BorderColor = UIColor.Black.CGColor;
sheet.AddSubview(subView);
NavigationController.Add(sheet);
You can show an ActionSheet using the ShowFrom methods.
In particular, ShowFromToolbar shows the sheet from the top toolbar button.
Here's an example which shows the sheet in different ways depending on whether you are on tablet or phone:
void ActionMenu()
{
//_actionSheet = new UIActionSheet("");
UIActionSheet actionSheet = new UIActionSheet (
"Customer Actions",
null,
"Cancel",
"Delete Customer",
new string[] {"Change Customer"});
actionSheet.Style = UIActionSheetStyle.Default;
actionSheet.Clicked += delegate(object sender, UIButtonEventArgs args) {
switch (args.ButtonIndex)
{
case 0: DeleteCustomer(); break;
case 1: ChangeCustomer(); break;
}
};
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone)
actionSheet.ShowFromToolbar(NavigationController.Toolbar);
else
actionSheet.ShowFrom(NavigationItem.RightBarButtonItem, true);
}
https://github.com/slodge/MvvmCross-Tutorials/blob/master/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement.Touch/Views/CustomerView.cs#L67
I have a dataset that returns questions and answers from the database, each answer in answer table is linked via a forgein key to the question table.
What I would like to achive is the following:
That a a single dynamic form is created on the first question with all the questions listed under it, meaning the FK_table_Answers = PK_table_Questions on the table_Answers:
(eg) This is Form for Question One:
Question One: How old are you?
Answer One (this is a radio button)
Answer Two (this is a radio button)
Answer Three (this is a radio button)
I have managed to get the above kind of working but the problem is my code keeps generating the forms (eg) 3 times becuase there are three answers, so can anyone point me in right direction how to generate the form dynamically but only ONCE - meaning each successive form is created only once as per the question and that particular questions answers under it.
Kind regards
UPDATED code:
private void LoadDataSets()
{
if (_dataSetQuestionnaire.tbl_QuestionnaireQuestion.Rows.Count == 0)
{
try
{
//Questionnaire:
DataSet1TableAdapters.tbl_QuestionnaireTableAdapter questionnaireAdapter =
new DataSet1TableAdapters.tbl_QuestionnaireTableAdapter();
questionnaireAdapter.Fill(_dataSetQuestionnaire.tbl_Questionnaire);
//Category:
DataSet1TableAdapters.tbl_QuestionnaireCategoryTableAdapter categoryAdapter =
new DataSet1TableAdapters.tbl_QuestionnaireCategoryTableAdapter();
categoryAdapter.Fill(_dataSetQuestionnaire.tbl_QuestionnaireCategory);
//QuestionnaireQuestion:
DataSet1TableAdapters.tbl_QuestionnaireQuestionTableAdapter questionnaireQuestionAdapter =
new DataSet1TableAdapters.tbl_QuestionnaireQuestionTableAdapter();
questionnaireQuestionAdapter.Fill(_dataSetQuestionnaire.tbl_QuestionnaireQuestion);
//QuestionnaieAnswer:
DataSet1TableAdapters.tbl_QuestionnaireAnswerTableAdapter questionnaireAnswerAdapter =
new DataSet1TableAdapters.tbl_QuestionnaireAnswerTableAdapter();
questionnaireAnswerAdapter.Fill(_dataSetQuestionnaire.tbl_QuestionnaireAnswer);
using (DataSet1 dSet = new DataSet1())
{
//Questionnaire:
dSet.Merge(_dataSetQuestionnaire.tbl_Questionnaire);
//Category:
dSet.Merge(_dataSetQuestionnaire.tbl_QuestionnaireCategory);
//QuestionnaireQuestion:
dSet.Merge(_dataSetQuestionnaire.tbl_QuestionnaireQuestion);
//QuestionnaieAnswer:
dSet.Merge(_dataSetQuestionnaire.tbl_QuestionnaireAnswer);
int primaryKeyQuestionnaire = Convert.ToInt32(_dataSetQuestionnaire.tbl_Questionnaire.Rows[0][0]);
foreach (DataSet1.tbl_QuestionnaireRow questionnaire
in _dataSetQuestionnaire.Tables["tbl_Questionnaire"].Select(String.Format("pk_tbl_Questionnaire = {0}", primaryKeyQuestionnaire)))
{
foreach (DataSet1.tbl_QuestionnaireCategoryRow category
in _dataSetQuestionnaire.Tables["tbl_QuestionnaireCategory"].Select(String.Format("fk_tbl_Questionnaire = {0}", questionnaire.pk_tbl_Questionnaire)))
{
foreach (DataSet1.tbl_QuestionnaireQuestionRow question
in _dataSetQuestionnaire.Tables["tbl_QuestionnaireQuestion"].Select(String.Format("fk_tbl_QuestionnaireCategory = {0}", category.pk_tbl_QuestionnaireCategory)))
{
int radiobuttonPosition = 0;
foreach (DataSet1.tbl_QuestionnaireAnswerRow answer
in _dataSetQuestionnaire.Tables["tbl_QuestionnaireAnswer"].Select(String.Format("fk_tbl_QuestionnaireQuestion = {0}", question.pk_tbl_QuestionnaireQuestion)))
{
//Gets the questins via the FK_questionnaireQuestion and fill the _dataSetRadioButtons to generate on dynamic form.
DataSet1TableAdapters.tbl_QuestionnaireAnswerTableAdapter a =
new DataSet1TableAdapters.tbl_QuestionnaireAnswerTableAdapter();
DataSet dSetRadioButtons = new DataSet();
dSetRadioButtons.Merge(a.GetDataByQuestionnaireQuestion(answer.fk_tbl_QuestionnaireQuestion));
_dataSetRadioButtons = dSetRadioButtons;
string theQuestion = question.tbl_QuestionnaireQuestion_Description.ToString();
Form form = new Form();
_form = form;
if(_form == null)
{
_form = new Form();
}
else
{
form.Height = 400;
form.Width = 550;
form.StartPosition = FormStartPosition.CenterScreen;
Label label = new Label();
label.Location = new System.Drawing.Point(5, 10);
label.Size = new System.Drawing.Size(450, 25);
label.Text = theQuestion;
Panel panel = new Panel();
panel.Size = new System.Drawing.Size(300, 200);
panel.Location = new System.Drawing.Point(15, 50);
panel.BackColor = Color.Yellow;
System.Windows.Forms.RadioButton[] radioButtons = new System.Windows.Forms.RadioButton[_dataSetRadioButtons.Tables["tbl_QuestionnaireAnswer"].Rows.Count];
for (int i = 0; i < _dataSetRadioButtons.Tables["tbl_QuestionnaireAnswer"].Rows.Count; i++)
{
radioButtons[i] = new RadioButton();
radioButtons[i].Text = _dataSetRadioButtons.Tables["tbl_QuestionnaireAnswer"].Rows[i]["tbl_QuestionnaireAnswer_Description"].ToString();
radioButtons[i].Location = new System.Drawing.Point(60, 20 + i * 20);
//panel.Controls.Add(radioButtons[i]);
radioButtons[i].Click += new EventHandler(Form1_Click);
Int64 item = Convert.ToInt64(_dataSetRadioButtons.Tables["tbl_QuestionnaireAnswer"].Rows[0].ItemArray[3].ToString());
panel.Controls.Add(radioButtons[i]);
}
Button nextButton = new Button();
nextButton.Text = "Next";
nextButton.Name = "button";
nextButton.Location = new System.Drawing.Point(200, 300);
nextButton.Size = new System.Drawing.Size(150, 25);
nextButton.Click += new EventHandler(nextButton_Click);
form.Controls.AddRange(new Control[] { panel, label, nextButton });
form.ShowDialog();
CreateBoxAndQuestion(form, panel, label);
//form.Dispose();
}
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
MessageBox.Show("Error");
}
}
private void CreateBoxAndQuestion(Form f, Panel p, Label l)
{
for (int i = p.Controls.Count - 1; i >= 0; i--)
{
p.Controls.RemoveAt(i);
}
}
If I understand correctly, you call CreateBoxAndQuestion every time a new question is selected.
But you create (and destroy) the form each time your code enters in this method.
A first approach would be to keep the form, label, button and panel creation outside the method (perhaps in design mode) then passing these controls to the method as
EDIT: Somewhere in your code before entering the load of your next question:
frmQuestion _form = null; // Global
// Create a global instance and keep it without displaying
if(_form == null) _form = new frmQuestion(); // frmQuestion created with panel, label e button via FormDesigner
then when you need to populate _form call
CreateBoxAndQuestion(_form, _form.Panel, _form.Label, questionText);
In this example I pass the _form to CreateBoxAndQuestion, but this is not necessary because is a global. You could change CreateBoxAndQuestion to use directly the global instance.
private void CreateBoxAndQuestion(frmQuestion f, Panel p, Label l, string _label)
{
// Do not display your form here....
}
Now when entering the method clear every RadioButton controls in the panel.Controls collection
for (int i = p.Controls.Count - 1; i >= 0; i--)
{
p.Controls.RemoveAt(i);
}
the rest of the code should change only to reflect the new text assigned to the label and controls and the re-adding of the RadioButtons to the panel. No more creation and reinitialization for Form Label, Button.
label.Text = _label;
Don't forget to destroy _form at the end of your program with _form.Dispose();