Why does it fill only first group box? - c#

I have a test, and in Form1_Load I fill up this test with questions and answers. But it shows only first question. What's the matter?
int loc = 20;
for (int i = 0; i < 5; i++)
{
GroupBox gb = new GroupBox();
gb.Size = new Size(500, 200);
gb.Location = new Point(40, loc);
gb.BackColor = System.Drawing.Color.Aquamarine;
Label q_text = new Label(); // текст питання
q_text.Text = "Питання" + (i + 1);
q_text.Font = new Font("Aria", 10, FontStyle.Bold);
q_text.Location = new Point(gb.Location.X, gb.Location.Y);
gb.Controls.Add(q_text);
int iter = q_text.Location.Y + 30;
foreach (string key in questions[i].answers.Keys)
{
RadioButton rb = new RadioButton();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
this.Controls.Add(gb);
loc += 300;
}

After examining your code, there are a few possible issues stemming from q_text
int loc = 20;
for (int i = 0; i < 5; i++)
{
GroupBox gb = new GroupBox();
gb.Size = new Size(500, 200);
gb.Location = new Point(40, loc);
gb.BackColor = System.Drawing.Color.Aquamarine;
Label q_text = new Label(); // текст питання
q_text.Text = "Питання" + (i + 1);
q_text.Font = new Font("Aria", 10, FontStyle.Bold);
q_text.Location = new Point(0, 0);
gb.Controls.Add(q_text);
int iter = q_text.Location.Y + 30;
foreach (string key in questions[i].answers.Keys)
{
RadioButton rb = new RadioButton();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
this.Controls.Add(gb);
loc += 300;
}
The only changes here are q_text getting set to 0,0.
An additional change I would make however is to adjust hight by q_text's height:
int iter = q_text.Location.Y + q_text_Size.Height + 5;
Just in case the label was long and wrapped text.

Related

Can c# windows form list view have item template with 2 rows and 2 columns

I have a list of items that is constantly updated from live readings, the newest items should be added on the top of the list.
is it possible to have an item template for the list view with 2 rows and 2 column for each item. (like attached photo).
I searched online i could not find a solution.
my second approach was to create Main Panel and append Panels to it sub panels to it containing the labels.I am only able to add the items in the bottom of the Main panel since i can calculate the location of the last added item.
Panel pan = new Panel();
pan.Name = "panel" + counter;
pan.BorderStyle = BorderStyle.FixedSingle;
Label label1 = new Label();
label1.AutoSize = true;
label1.Location = new System.Drawing.Point(0, 0);
label1.Name = "label" + counter;
label1.Size = new System.Drawing.Size(35, 13);
label1.TabIndex = 1;
label1.Text = "label" + counter;
Label label2 = new Label();
label2.AutoSize = true;
label2.Location = new System.Drawing.Point(0, 20);
label2.Name = "label2" + counter;
label2.Size = new System.Drawing.Size(35, 13);
label2.TabIndex = 2;
label2.Text = "label2" + counter;
Label label3 = new Label();
label3.AutoSize = true;
label3.Location = new System.Drawing.Point(40, 0);
label3.Name = "label3" + counter;
label3.Size = new System.Drawing.Size(35, 13);
label3.TabIndex = 3;
label3.Text = "label3" + counter;
Label label4 = new Label();
label4.AutoSize = true;
label4.Location = new System.Drawing.Point(40, 20);
label4.Name = "label4" + counter; ;
label4.Size = new System.Drawing.Size(35, 13);
label4.TabIndex = 4;
label4.Text = "label4" + counter;
pan.Location = new Point(0, counter * 50);
pan.Size = new Size(100, 50);
pan.Controls.Add(label1);
pan.Controls.Add(label2);
pan.Controls.Add(label3);
pan.Controls.Add(label4);
MainPanel.Controls.Add(pan);
counter++;
Thanks

Button_click event(in code) for every button in multiple GroupBox

I have multiple groupbox, which one contains a question and some answers and button ANSWER in each GroupBox. I create GroupBox and its Controls in Form_Load Method, not manually. How to handle button_click events for every button? I think it's not necessary to write this handle method for every button, because there are only two different button_handler: for questions where there can be only one correct answers, and for questions, where multiple answers can be correct.
My questions look like:
My GroupBox structure:
int loc = 20;
for (int i = 0; i < 10; i++)
{
GroupBox gb = new GroupBox();
gb.Name = "GroupBox" + (i + 1);
gb.Size = new Size(500, 200);
gb.Location = new Point(40, loc);
gb.BackColor = System.Drawing.Color.Aquamarine;
Label q_text = new Label(); // текст питання
q_text.Name = "label" + (i + 1);
q_text.Text = "Питання" + (i + 1);
q_text.Font = new Font("Aria", 10, FontStyle.Bold);
q_text.Location = new Point(10, 10);
gb.Controls.Add(q_text);
int iter = q_text.Location.Y + 30;
if (i <= 5)
{
foreach (string key in questions[i].answers.Keys)
{
RadioButton rb = new RadioButton();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
}else
if (i > 5)
{
foreach (string key in questions[i].answers.Keys)
{
CheckBox rb = new CheckBox();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
}
Button b = new Button();
b.Name = "button" + (i + 1);
b.Text = "Answer";
b.Location = new Point(gb.Size.Width - 120, gb.Size.Height - 30);
gb.Controls.Add(b);
this.Controls.Add(gb);
loc += 200;
}
You can create a general click event for your buttons:
Button b = new Button();
b.Name = "button" + (i + 1).ToString();
b.Click += b_Click;
and in the method, examine the sender to see which button was clicked:
void b_Click(object sender, EventArgs e) {
Button b = sender as Button;
if (b != null) {
GroupBox gp = b.Parent as GroupBox;
int bIndex = Convert.ToInt32(b.Name.Substring(6)) - 1;
MessageBox.Show(string.Format("I'm clicking {0}, question index #{1}",
gp.Name, bIndex));
}
}
After that, you would have to examine the checked values of your GroupBox child controls with the allowable answers in the questions[bIndex].answers variable.

Adding objects to a GroupBox issue

I am trying to add different objects to a GroupBox. When I click 'Add Title' button I can get the Combobox and Textbox to appear in the Groupbox.
What I want to now happen is when they click 'Add question' I want to be able to add the questions objects (Combobox, Textbox) to the same Groupbox as the last added title.
C# CODE:
private void btnAddTitle_Click(object sender, RoutedEventArgs e)
{
CurrentSortItem++;
SortItems.Add(CurrentSortItem);
StackPanel sp = new StackPanel() { Orientation = Orientation.Horizontal };
gp = new GroupBox();
ComboBox y = new ComboBox();
y.Name = "Combo" + CurrentSortItem;
y.SelectedItem = CurrentSortItem;
y.Height = 25;
y.Width = 45;
y.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
y.Margin = new Thickness(20, 15, 0, 0);
foreach (int item in SortItems)
{
y.Items.Add(item);
}
TextBox x = new TextBox();
x.Name = "Title" + CurrentSortItem;
x.Text = "Title...";
x.FontWeight = FontWeights.Bold;
x.FontStyle = FontStyles.Italic;
x.TextWrapping = TextWrapping.Wrap;
x.Height = 25;
x.Width = 200;
x.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
x.Margin = new Thickness(12, 15, 0, 0);
sp.Children.Add(y);
sp.Children.Add(x);
gp.Content = sp;
spStandard.Children.Add(gp);
}
private void ViewQuestions(StackPanel sp)
{
gp.Content = sp;
}
List<int> SortItems1 = new List<int>();
int CurrentSortItem1 = 0;
int Count = 0;
private void btnQuestion_Click(object sender, RoutedEventArgs e)
{
if (SortItems.Count == 0)
{
MessageBox.Show("You must add a title before adding a question", "ERROR", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
Count++;
CurrentSortItem1++;
SortItems1.Add(CurrentSortItem1);
StackPanel sp = new StackPanel() { Orientation = Orientation.Horizontal };
ComboBox y = new ComboBox();
y.Name = "Combo" + CurrentSortItem1;
y.SelectedItem = CurrentSortItem1;
y.Height = 25;
y.Width = 45;
y.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
y.Margin = new Thickness(20, 15, 0, 0);
foreach (int item in SortItems1)
{
y.Items.Add(item);
}
TextBox x = new TextBox();
x.Name = "Question" + CurrentSortItem1;
x.Text = "Question...";
x.FontStyle = FontStyles.Italic;
x.TextWrapping = TextWrapping.Wrap;
x.Height = 25;
x.Width = 500;
x.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
x.AcceptsReturn = true;
x.Margin = new Thickness(100, 15, 0, 0);
TextBox z = new TextBox();
z.Name = "Points" + CurrentSortItem;
z.FontWeight = FontWeights.Bold;
z.Height = 25;
z.Width = 45;
z.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
z.Margin = new Thickness(250, 15, 0, 0);
sp.Children.Add(y);
sp.Children.Add(x);
sp.Children.Add(z);
ViewQuestions(sp);
}
I have tried to have an attempted but when I click 'Add Question' it just overwrites the Title's objects.
Any help would be amazing.
I am using WPF, and these are created at runtime.
Thanks.
EDIT4:
I have had to move
StackPanel outerSp = new StackPanel() { Orientation = Orientation.Vertical };
StackPanel sp = new StackPanel() { Orientation = Orientation.Horizontal };
GroupBox gp;
Just below the
public partial class CreateNewStandard : Page
{
So it is visible to all the methods. Then I get this error.
http://i.stack.imgur.com/f9uqF.png
Try this
private void btnAddTitle_Click(object sender, RoutedEventArgs e)
{
CurrentSortItem++;
SortItems.Add(CurrentSortItem);
StackPanel outerSp = new StackPanel() { Orientation = Orientation.Vertical };
StackPanel sp = new StackPanel() { Orientation = Orientation.Horizontal };
gp = new GroupBox();
ComboBox y = new ComboBox();
y.Name = "Combo" + CurrentSortItem;
y.SelectedItem = CurrentSortItem;
y.Height = 25;
y.Width = 45;
y.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
y.Margin = new Thickness(20, 15, 0, 0);
foreach (int item in SortItems)
{
y.Items.Add(item);
}
TextBox x = new TextBox();
x.Name = "Title" + CurrentSortItem;
x.Text = "Title...";
x.FontWeight = FontWeights.Bold;
x.FontStyle = FontStyles.Italic;
x.TextWrapping = TextWrapping.Wrap;
x.Height = 25;
x.Width = 200;
x.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
x.Margin = new Thickness(12, 15, 0, 0);
sp.Children.Add(y);
sp.Children.Add(x);
outerSp.Children.Add(sp);
gp.Content = outerSp;
spStandard.Children.Add(gp);
}
private void ViewQuestions(StackPanel sp)
{
var stackPanel=gp.Content as StackPanel;
if(stackPanel!=null)
{
stackPanel.Children.Add(sp);
}
else
gp.Content=sp;
}
List<int> SortItems1 = new List<int>();
int CurrentSortItem1 = 0;
int Count = 0;
private void btnQuestion_Click(object sender, RoutedEventArgs e)
{
if (SortItems.Count == 0)
{
MessageBox.Show("You must add a title before adding a question", "ERROR", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
Count++;
CurrentSortItem1++;
SortItems1.Add(CurrentSortItem1);
ComboBox y = new ComboBox();
y.Name = "Combo" + CurrentSortItem1;
y.SelectedItem = CurrentSortItem1;
y.Height = 25;
y.Width = 45;
y.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
y.Margin = new Thickness(20, 15, 0, 0);
foreach (int item in SortItems1)
{
y.Items.Add(item);
}
TextBox x = new TextBox();
x.Name = "Question" + CurrentSortItem1;
x.Text = "Question...";
x.FontStyle = FontStyles.Italic;
x.TextWrapping = TextWrapping.Wrap;
x.Height = 25;
x.Width = 500;
x.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
x.AcceptsReturn = true;
x.Margin = new Thickness(100, 15, 0, 0);
TextBox z = new TextBox();
z.Name = "Points" + CurrentSortItem;
z.FontWeight = FontWeights.Bold;
z.Height = 25;
z.Width = 45;
z.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
z.Margin = new Thickness(250, 15, 0, 0);
sp.Children.Add(y);
sp.Children.Add(x);
sp.Children.Add(z);
outerSp.Children.Add(sp);
ViewQuestions(sp);
}
You are overwriting it .Though you need to add them to the already existing stackPanel. The code is not tested I am trying to give you an idea .I hope this will help.

Arrangments of dynamic created control in Grid View

Here is my code to get values from XML file:
foreach (XmlNode node in DOC.SelectNodes("//CheckMarkObject"))
{
FbCheckMark checkmark = new FbCheckMark();
checkmark.Name = node.SelectSingleNode("Name").InnerText;
checkmark.Label = node.SelectSingleNode("Label").InnerText;
if (node.SelectSingleNode("IsChecked").InnerText == "0")
{
checkmark.IsChecked = false;
}
else
{
checkmark.IsChecked = true;
}
listCheckMarks.Add(checkmark);
}
Now the code to create control at runtime:
for (int i = 0; i < listCheckMarks.Count; i++)
{
if (listCheckMarks[i].checkMark.Equals(checkMark))
{
CheckBox cb = new CheckBox();
TextBlock cbtextblock = new TextBlock();
cbtextblock.Text = listCheckMarks[i].Label;
cbtextblock.Height = 27;
cbtextblock.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
cbtextblock.Margin = new Thickness(12, 20, 0, 0);
cbtextblock.VerticalAlignment = System.Windows.VerticalAlignment.Top;
cb.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
cb.VerticalAlignment = System.Windows.VerticalAlignment.Top;
cb.Margin = new Thickness(150, 21, 0, 0);
cb.Height = 50;
cb.Width = 100;
cb.Name = listCheckMarks[i].Name;
LayoutRoot.Children.Add(cbtextblock);
LayoutRoot.Children.Add(cb);
}
}
when i made change in my XML file i.e Create "CheckMark" tag two times. the result control overwrite on previous one. i want to arrange the new control under the previous one.
kindly suggest me what can i do ? use linear layout like in android?
thanks
Try to insert elements into StackPanel and set Orientation property for it.
Try that example:
StackPanel container = new StackPanel();
LayoutRoot.Children.Add(container);
for (int i = 0; i < listCheckMarks.Count; i++)
{
if (listCheckMarks[i].checkMark.Equals(checkMark))
{
StackPanel childContainer = new StackPanel();
childContainer.Orientation = Orientation.Horizontal;
CheckBox cb = new CheckBox();
TextBlock cbtextblock = new TextBlock();
cbtextblock.Text = listCheckMarks[i].Label;
cbtextblock.Height = 27;
cbtextblock.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
cbtextblock.Margin = new Thickness(12, 20, 0, 0);
cbtextblock.VerticalAlignment = System.Windows.VerticalAlignment.Top;
cb.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
cb.VerticalAlignment = System.Windows.VerticalAlignment.Top;
cb.Margin = new Thickness(150, 21, 0, 0);
cb.Height = 50;
cb.Width = 100;
cb.Name = listCheckMarks[i].Name;
childContainer.Children.Add(cbtextblock);
childContainer.Children.Add(cb);
container.Children.Add(childContainer);
}
}

DatePicker anonymous event handler

I have a WPF form that I have created programatically. It is basically a list of items with 2 DatePicker objects to specify a range of dates. I have everything working for the most part, but I need to fire some logic on the SelectedDateChanged event.
The problem is, since the DatePicker's are generated dynamically based on selections from a previous form, I need to use an anonymous listener (or whatever you call them in .NET). I have been unable to do it the way I know how and I cant seem to find any example or help through google either. Thanks in advance for any tips.
Generating DatePickers:
public SystemInterval(Role role)
{
this.role = role;
InitializeComponent();
lbls = new Label[role.RoleSystems.Length];
dp = new DatePicker[role.RoleSystems.Length * 2];
cks = new CheckBox[role.RoleSystems.Length];
ScrollViewer sv = new ScrollViewer();
sv.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
sv.VerticalAlignment = System.Windows.VerticalAlignment.Top;
sv.Margin = new Thickness(0,50,0,40);
Grid g = new Grid();
g.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
g.VerticalAlignment = System.Windows.VerticalAlignment.Top;
ColumnDefinition col1 = new ColumnDefinition();
col1.Width = new GridLength(46);
ColumnDefinition col2 = new ColumnDefinition();
col2.Width = GridLength.Auto;
ColumnDefinition col3 = new ColumnDefinition();
col3.Width = new GridLength(150);
ColumnDefinition col4 = new ColumnDefinition();
col4.Width = new GridLength(150);
g.ColumnDefinitions.Add(col1);
g.ColumnDefinitions.Add(col2);
g.ColumnDefinitions.Add(col3);
g.ColumnDefinitions.Add(col4);
sv.Content = g;
LayoutRoot.Children.Add(sv);
for (int r = 0; r < cks.Length; r++)
{
g.RowDefinitions.Add(new RowDefinition());
}
g.Height = (lbls.Length * 25) + (lbls.Length * 5);
for (int i = 0, j = 0; i < cks.Length; i++, j+=2)
{
cks[i] = new CheckBox();
cks[i].IsChecked = false;
cks[i].VerticalAlignment = System.Windows.VerticalAlignment.Center;
cks[i].HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
Grid.SetColumn(cks[i], 0);
Grid.SetRow(cks[i], i);
g.Children.Add(cks[i]);
lbls[i] = new Label();
lbls[i].Height = 25;
lbls[i].Content = role.RoleSystems[i].SystemName;
lbls[i].VerticalAlignment = System.Windows.VerticalAlignment.Center;
lbls[i].HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
Grid.SetColumn(lbls[i], 1);
Grid.SetRow(lbls[i], i);
g.Children.Add(lbls[i]);
dp[j] = new DatePicker();
dp[j].Height = 25;
dp[j].Width = 115;
dp[j].VerticalAlignment = System.Windows.VerticalAlignment.Center;
dp[j].HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
dp[j].IsEnabled = false;
dp[j].BlackoutDates.Add(new CalendarDateRange(new DateTime(0001, 1, 1), DateTime.Now.Subtract(TimeSpan.FromDays(1))));
Grid.SetColumn(dp[j], 2);
Grid.SetRow(dp[j], i);
g.Children.Add(dp[j]);
dp[j + 1] = new DatePicker();
dp[j + 1].Height = 25;
dp[j + 1].Width = 115;
dp[j + 1].VerticalAlignment = System.Windows.VerticalAlignment.Center;
dp[j + 1].HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
dp[j + 1].IsEnabled = false;
dp[j + 1].BlackoutDates.Add(new CalendarDateRange(new DateTime(0001, 1, 1), DateTime.Now));
Grid.SetColumn(dp[j + 1], 3);
Grid.SetRow(dp[j + 1], i);
g.Children.Add(dp[j + 1]);
cks[i].Click += new RoutedEventHandler(delegate(object s, RoutedEventArgs re)
{
CheckBox cb = (CheckBox)re.Source;
for (int r = 0; r < cks.Length; r++)
{
if (cks[r].Equals(cb))
{
dp[r * 2].IsEnabled = true;
dp[r * 2 + 1].IsEnabled = true;
}
}
});
}
The checkboxs have an anonymous event handler, however this does not work for the DatePicker.SelectedDateChanged event.
Do you mean an event handler using an anonymous method like this?
var dp = new DatePicker();
dp.SelectedDateChanged +=
(sender, args) =>
{
var picker = (DatePicker) sender;
/* do stuff here */
};

Categories