C# MDI Event Help - c#

I have a form which is an MDI container. In that form i generate 6 child forms each with a label:
for (int i = 0; i < 6; i++)
{
Form window = new Form();
window.Width = 100;
window.Height = 100;
window.MdiParent = this;
window.FormBorderStyle = FormBorderStyle.FixedToolWindow;
Label label = new Label();
label.AutoSize = true;
label.Location = new System.Drawing.Point(1, 1);
label.Size = new System.Drawing.Size(35, 13);
label.TabIndex = 1;
label.Name = "label" + i.ToString();
label.Text = window.Top.ToString();
window.LocationChanged += new System.EventHandler(HERE);
window.Controls.Add(label);
window.Show();
}
I added an event on the locationchanged for window. Now how do do it so that label updates to the windows position?

I think this line will do the trick for you:
window.LocationChanged += new EventHandler(delegate(object o, EventArgs evtArgs) {
label.Text = window.Location.ToString();
});

Well, it's easiest to do it with a lambda expression or an anonymous method:
window.LocationChanged += (sender, args) => label.Text = window.Top.ToString();
If you're using C# 1.1 you'd need to be a bit trickier because of the label being captured automatically in C# 2+ - you'd have to create a new class like this:
internal class LocationChangeNotifier
{
private readonly Label label;
internal LocationChangeNotifier(Label label)
{
this.label = label;
}
internal void HandleLocationUpdate(object sender, EventArgs e)
{
label.Text = ((Control) sender).Top.ToString();
}
}
then use it as:
LocationChangeNotifier notifier = new LocationChangeNotifier(label);
window.LocationChanged += new EventHandler(notifier.HandleLocationUpdate);
Aren't captured variables great? :)

Related

How to apply a Focus() function on Dynamically Created TextBox in windows forms?

When dynamically creating textBoxes how can we make one of the textBoxes have the Focus() function on it?
namespace Dinamik_Arac
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 5; i++)
{
TextBox txt = new TextBox();
Point txtKonum = new Point(300, i * 30);
txt.Location = txtKonum;
txt.Name = "TextBox" + i;
txt.Text = i.ToString();
this.Controls.Add(txt);
}
}
}
}
Simply writing TextBox4.Focus() into the for loop is not working.
for (int i = 1; i <= 5; i++)
{
TextBox txt = new TextBox();
Point txtKonum = new Point(300, i * 30);
txt.Location = txtKonum;
txt.Name = "TextBox" + i;
txt.Text = i.ToString();
if(i == 4)
{
txt.Focus();
}
this.Controls.Add(txt);
}
This code does not work either.
enter image description here
As you can see in the picture there is no cursor on the 4th textBox.
Solved,
just put the this.Controls.Add(txt); code before the if statement,
{
TextBox txt = new TextBox();
Point txtKonum = new Point(300, i * 30);
txt.Location = txtKonum;
txt.Name = "TextBox" + i;
txt.Text = i.ToString();
this.Controls.Add(txt);
if(i == 4)
{
txt.Focus();
}
}
I've been playing around with this problem looking for an alternative and more versatile approach, and I came up with this method for giving focus to your your 4th iteration of dynamically created textboxes:
string focusedTextBox = "TextBoxName";//in this case "Textbox4"
Control focusControl = this.Controls[focusedTextBox];
focusControl.Focus();
In your application, it would look like this:
private void button1_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 5; i++)
{
TextBox txt = new TextBox();
Point txtKonum = new Point(300, i * 30);
txt.Location = txtKonum;
txt.Name = "TextBox" + i;
txt.Text = i.ToString();
this.Controls.Add(txt);
}
Control focusControl = this.Controls["Textbox4"];
focusControl.Focus();
}
The obvious major advantage to this approach is that it will work from other places in the program. The only thing that has to be taken into account when calling this from a seperate method is that if the control.name doesn't exist an exception will be thrown, so it would probably be a good idea to set up some sort of safeguard or exception handling for that usage.

C# activeform controls property

I am unable to get the controls count on the newly created form on the newly created button, I have created 5 controls but only one is showing. If I cannot get the total control count then I cannot also get the control type, name etc.
private void button2_Click(object sender, EventArgs e)
{
Form frm = new Form();
frm.Text = "new form";
TableLayoutPanel tlp = new TableLayoutPanel();
tlp.AutoSize = true;
Button btn = new Button();
btn.Text = "ok";
tlp.Controls.Add(btn, 0, 4);
frm.Controls.Add(tlp);
for (int i = 3, ii = 0; i >= 0; i--, ii++)
{
TextBox tbx = new TextBox();
tlp.Controls.Add(tbx, 0, ii);
}
frm.Show();
string str = frm.Controls.Count.ToString();
btn.Click += (s, args) =>
{
MessageBox.Show(frm.Text);
MessageBox.Show(ActiveForm.Text);
MessageBox.Show(str);
};
}
In your code the only Control that you've added to your form is a TableLayoutPanel that contains TextBox controls. That is why the count is 1.

Make dynamically created panels in winform responsive (same size as my flowlayoutPanel) - C#

So I'm creating some panels with the following code
private void button1_Click(object sender, EventArgs e)
{
int xlocation = 5;
for (int i = 0; i < 10; i++)
{
Panel panel = new Panel();
{
panel.Name = string.Format("{0}", i);
panel.Text = string.Format(i.ToString());
panel.BackColor = Color.White;
panel.Location = new System.Drawing.Point(xlocation, 30);
panel.Width = flowLayoutPanel1.Width;
panel.Height = 50;
panel.MouseEnter += new System.EventHandler(this.panel_MouseEnter);
flowLayoutPanel1.Controls.Add(panel);
Label label = new Label();
label.Location = new System.Drawing.Point(15, 10);
label.AutoSize = true;
label.Font = new System.Drawing.Font("Calibri", 13F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
label.ForeColor = System.Drawing.Color.FromArgb(64, 64, 64);
label.Text = string.Format("{0}", "GNU" + i);
panel.Controls.Add(label);
Label label10 = new Label();
label10.Location = new System.Drawing.Point(15, 35);
label10.AutoSize = true;
label10.Font = new System.Drawing.Font("Calibri", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
label10.ForeColor = System.Drawing.Color.FromArgb(64, 64, 64);
label10.Text = string.Format("{0}", "hest");
panel.Controls.Add(label10);
}
xlocation = xlocation + 85;
}
}
The problem is when I resize my form, my flowLayoutPanel obviously gets bigger, but the panels inside doesn't.
I have tried using the
private void Form1_Resize(object sender, EventArgs e)
{
}
But it doesn't seem to work.
Any answer is much appreciated!
Thanks!
You can either use the Anchor property and set it to Right and Left, or can dock each panel to parent control. Something like this should work:
Panel panel = new Panel();
panel.Dock = DockStyle.Top; // Docks the panel to top, and fills to the width of Parent control
panel.Anchor = (AnchorStyles.Right | AnchorStyles.Left); // Set anchor to right and left
I found a solution. I just created a list with my panels like so
List<Panel> pnls = new List<Panel>();
And just did like so to make them follow the width of my flowlayoutpanel, so you can actually use a flowlayoutpanel ;-)
private void Kontrol_Resize(object sender, EventArgs e)
{
for (int i = 0; i < pnls.Count; i++)
{
pnls[i].Width = activityData.Width - 24;
pnls[i].Height = activityData.Height / 4;
}
}

Winforms RadPageView find control

I have nested controls inside RadPageView control on a Winform application. RadPageView has a child RadPageViewPage. These two controls are on the form however a tab control and inside that tab control some other controls are added dynamically. How can I find and change the value of the Textbox inside the dynamically generated tab control on a click of the button.
public Form1()
{
InitializeComponent();
TabControl tb = new TabControl();
tb.Width = 500;
TabPage tp = new TabPage("Tab 1");
Label lb = new Label();
lb.Text = "Test";
lb.Location = new Point(10, 10);
TextBox txt = new TextBox();
txt.Text = "Textbox";
txt.Location = new Point(200, 10);
tp.Controls.Add(lb);
tp.Controls.Add(txt);
tb.Controls.Add(tp);
radPageViewPage1.Controls.Add(tb);
}
private void button1_Click(object sender, EventArgs e)
{
}
I have found this example over the internet and its working perfectly.
public Form1()
{
InitializeComponent();
TabControl tb = new TabControl();
tb.Width = 500;
TabPage tp = new TabPage("Tab 1");
Label lb = new Label();
lb.Text = "Test";
lb.Name = "lblTest";
lb.Location = new Point(10, 10);
TextBox txt = new TextBox();
txt.Text = "Textbox";
txt.Name = "txtName";
txt.Location = new Point(200, 10);
tp.Controls.Add(lb);
tp.Controls.Add(txt);
tb.Controls.Add(tp);
radPageViewPage1.Controls.Add(tb);
}
private void button1_Click(object sender, EventArgs e)
{
var crl = FindControl("txtName");
MessageBox.Show(crl.Text);
}
Control FindControl(string target)
{
return FindControl(this, target);
}
static Control FindControl(Control root, string target)
{
if (root.Name.Equals(target))
return root;
for (var i = 0; i < root.Controls.Count; ++i)
{
if (root.Controls[i].Name.Equals(target))
return root.Controls[i];
}
for (var i = 0; i < root.Controls.Count; ++i)
{
Control result;
for (var k = 0; k < root.Controls[i].Controls.Count; ++k)
{
result = FindControl(root.Controls[i].Controls[k], target);
if (result != null)
return result;
}
}
return null;
}

FlowLayoutPanel line between rows

I am trying to build a grid of companies generated from my database.
I set my flowlayout as topdown. Is it possible to put a line between rows like this http://data.worldbank.org/country
If needed, my code posted below.
public void createLinks(string[] groupNames)
{
for (int i = 0; i < groupNames.Length; i++)
{
LinkLabel obj = new LinkLabel();
obj.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline;
obj.LinkColor = Color.Black;
obj.Name = groupNames[i];
obj.Text = groupNames[i];
obj.Click += delegate(object sender, EventArgs e)
{LinkLabel ss = sender as LinkLabel;
frmCompanyReport test = new frmCompanyReport(ss.Name);
test.Show();
};
flowLayoutPanel1.Controls.Add(obj);
}
}
One solution is to use a Label to act as a line. Set AutoSize to False, Height to 1, and BorderStyle to FixedSingle. Then set the Width to the same as the FlowLayoutPanel.
Something like:
public void createLinks(string[] groupNames)
{
for (int i = 0; i < groupNames.Length; i++)
{
LinkLabel obj = new LinkLabel();
obj.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline;
obj.LinkColor = Color.Black;
obj.Name = groupNames[i];
obj.Text = groupNames[i];
obj.Click += delegate(object sender, EventArgs e)
{
LinkLabel ss = sender as LinkLabel;
frmCompanyReport test = new frmCompanyReport(ss.Name);
test.Show();
};
flowLayoutPanel1.Controls.Add(obj);
Label line = new Label();
line.AutoSize = false;
line.BorderStyle = BorderStyle.FixedSingle;
line.Height = 1;
line.Width = flowLayoutPanel1.Width;
flowLayoutPanel1.Controls.Add(line);
}
}

Categories

Resources