TextChanged event for dynamically created RichTextBoxes - c#

I'm trying to do a notepad with chrome-like tabs on it. I have a "New Page" button on my page. When I click on it, it creates a new tabpage with a richtexbox on it. The richboxes are created like this
public void yeni()
{
//create a new tabpage
TabPage newPage = new TabPage("Not-" + (tabControl1.TabPages.Count + 1));
//create a new richtexbox
RichTextBox rtb = new RichTextBox();
int rtbname = tabControl1.TabPages.Count + 1;
rtb.Name = "richTextBox" + rtbname.ToString();
rtb.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top);
rtb.BorderStyle = BorderStyle.None;
rtb.Width = 778;
rtb.Height = 395;
rtb.Location = new Point(0, 4);
rtb.HideSelection = false;
rtb.Font = new Font("Lucida Console", 9.75f);
rtb.ForeColor = Color.Maroon;
//add rtb to the tabpage
newPage.Controls.Add(rtb);
tabControl1.TabPages.Add(newPage);
//make the new created tab the selected one
tabControl1.SelectedTab = tabControl1.TabPages[tabControl1.TabPages.Count - 1];
//selectedRtb.Text = null;
openFileDialog1.FileName = null;
}
Now I create a RichTextBox and the name of that rtb is richTextBox*indexofthetabhere*. So if I'm working on the second tabpage, the name of the rtb is "richTextBox2". Now what I'm trying to do is I want an textchanged event for the richtextbox on the selected tabpage. I'm getting the selected richtextbox with this code here.
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
selectedone = "richTextBox" + (tabControl1.SelectedIndex+1).ToString();
selectedRtb = (RichTextBox)tabControl1.SelectedTab.Controls[selectedone];
textBox2.Text = selectedone;
}
Now here I get the selected tab index and i get the rtb name then I get the selected rtb as "selectedRtb". Now I can't make a textchanged event for this. I don't know what to do actually. I tested if the above code was working and yes I get the rtb names right. But I can't use them because I don't know how to do.. Thanks for the help.

public void yeni()
{
//....
RichTextBox rtb = new RichTextBox();
rtb.Name = "richTextBox" + selectedTabPageIndex.ToString();
rtb.TextChanged += rtb_TextChanged;
//....
}
void rtb_TextChanged(object sender, EventArgs e)
{
RichTextBox rtb = (RichTextBox)sender;
if (rtb.Name == "richTextBox" + selectedTabPageIndex.ToString())
{
//rtb is selected page richtextbox
//......
}
}

You don't know how to create events? Or you can't access something while knowing it's name (use reflection)?

Alright I solved my problem. Here is the answer;
selectedRtb.TextChanged += (bs, be) =>
{
//whatever you want to do
};
Simply added this to my code after I created the rtb, and it worked. Thanks to everyone who helped.

Related

Repositioning element on the form

I'm building that To-Do list app and I'm trying to create a "Add New task" button.
I wanted to create a new Task (TextBox) on the button click and also move the button bellow the TextBox added. So, I tried to create multiple panels and when the button was clicked, move the "New Task" button to the second panel and add the new textbox created to the first panel. And after that if the user wanted to remove that Task (TextBox), to repositionate the button and Tasks according to that.
Can someone please help me with that??
`
private void btnNewTask_Click(object sender, EventArgs e)
{
// Creating new Textbox
TextBox txtTask = new TextBox();
btnNewTask.Location = new Point(panel2);
// txtTask parameter
txtTask.BorderStyle = BorderStyle.None;
txtTask.ReadOnly = false;
txtTask.PlaceholderText = "Input a new Task.";
txtTask.Location = new Point(panel1);
//Adding txtTask.
this.Controls.Add(txtTask);
}
`
I founded The Solution. I deleted the panels and leaved the btnNewTask on the form.
On button click I needed to create and set the txtTask location as the btnNewTask location and change the Y location of btnNewTask to move it bellow. After that check if there was any other control that had the same or less Y location than txtTask, and if there was any, add 35 to his Y location too.
There is my new Code:
int c = 0;
private void btnNewTask_Click(object sender, EventArgs e)
{
// Creating new Textbox
TextBox txtTask = new TextBox();
// txtTask parameter
Font font = new Font("Segoe UI", 10.0f);
txtTask.Name = "txtTask" + ++c;
txtTask.BorderStyle = BorderStyle.None;
txtTask.ReadOnly = false;
txtTask.PlaceholderText = "Input a new Task.";
txtTask.Size = new Size(817, 31);
txtTask.Font = font;
txtTask.Location = new Point(btnNewTask.Location.X , btnNewTask.Location.Y); // txtTask will get the "btnNewTask" Location
btnNewTask.Location = new Point(txtTask.Location.X , btnNewTask.Location.Y + 35); // That should add 35 to the Y location
foreach (Control item in this.Controls)
{
if (item.Location.Y >= txtTask.Location.Y)
{ // if there is an item that has greater Y location
item.Location = new Point(item.Location.X, txtTask.Location.Y + 35); // It should increase its value as 35 too.
}
this.Controls.Add(txtTask);
}
There's an example:
Thank for the help and ideas!

Switching to dynamically created TabPage on button click

I'm practicing my coding and am trying to create a till by Dynamically prefill the items that are stored in a text file. I can dynamically create Tabs, Buttons and create menu buttons based on the categories of items. Where I'm struggling is I'm trying to switch the Tab on a button click. The Tabs are given a Name, which is the category ID, and the Text displays the category. In the event that trys to switch the tab I get the following error:
Error CS0266 Cannot implicitly convert type 'object' to 'System.Windows.Forms.TabPage'. An explicit conversion exists (are you missing a cast?)
I'm presuming that I need to Create a tab page or something, but I can't find out how to do this. Been on it for hours! Here's my code....
public partial class Form1 : Form
{
private void Form1_Load(object sender, EventArgs e)
{
string[] loadedFile = File.ReadAllLines(#"h:\shopItemsV2.txt");
foreach (string line in loadedFile)
{
// Split string and create required variables
string[] newBtnData = line.Split(',');
int catID = int.Parse(newBtnData[0]);
string cat = newBtnData[1];
string item = newBtnData[2];
double price = double.Parse(newBtnData[3]);
// Create tab if needed
if (tabControl1.TabCount < catID)
{
TabPage tp = new TabPage()
{
Text = cat,
Name = catID.ToString()
};
tabControl1.TabPages.Add(tp);
// Add FlowLayoutPanel with unique name
FlowLayoutPanel fp = new FlowLayoutPanel()
{
Name = "fp" + catID.ToString(),
Dock = DockStyle.Fill
};
// Add FlowLayoutPanel to correct Tab
tabControl1.TabPages[catID-1].Controls.Add(fp);
// Create Button for menu
Button newMenuBtn = new Button()
{
Name = cat + "Btn",
Tag = catID,
Width = 100,
Height = 50,
Text = cat,
};
newMenuBtn.Click += SwitchTab;
menuFP.Controls.Add(newMenuBtn);
}
// Create Button
Button newBtn = new Button()
{
Name = item,
Tag = price,
Width = 100,
Height = 100,
Text = item,
};
newBtn.Click += AddItem;
//Add button to correct tab
foreach (TabPage tabP in tabControl1.TabPages)
{
if (tabP.Name == catID.ToString())
{
Control fp = this.Controls.Find("fp"+catID, true).First();
fp.Controls.Add(newBtn);
}
}
}
}
private void SwitchTab(object sender, EventArgs e)
{
// Create button, switch to required Tab
// Tabs named the same as Tag on the button
Button clickedBtn = sender as Button;
tabControl1.SelectedTab = clickedBtn.Tag;
}
}
Any help would be greatly appreciated.
You can store anything in the Tag() property of your button. With that in mind, store a reference to your TabPage!
Change:
// Create Button for menu
Button newMenuBtn = new Button()
{
Name = cat + "Btn",
Tag = catID,
Width = 100,
Height = 50,
Text = cat,
};
To:
// Create Button for menu
Button newMenuBtn = new Button()
{
Name = cat + "Btn",
Tag = tp; // store the reference to the TabPage you created
Width = 100,
Height = 50,
Text = cat,
};
Then the suggestion by Uwe Keim should work:
tabControl1.SelectedTab = clickedBtn.Tag as TabPage;
private void AddNewPr_Click(object sender, EventArgs e)
{
TabPage tab = new TabPage();
_list = new ListBox();
_list2 = new ListBox();
PictureBox picBox = new PictureBox();
picBox.Click = picBox_Click;
//More stuff here
//Add the controls
tabControl1.Controls.Add(tab);
tab.Controls.Add(list);
tab.Controls.Add(list2);
tab.Controls.Add(pictureBox);
}

C# Adding custom richtextbox

I asked a question here
and im unsure how to add the class the user gave me - I have just created a new class file then pasted in the class and i dont know how to apply that to the richtextbox?
Heres how my richtextbox is found... I have a richtextbox for each tabpage opened in my text editor i created a new textbox on the newtab void
public RichTextBox GetRichTextBox()
{
RichTextBox rtb = null;
TabPage starting = tabControl1.SelectedTab;
if (starting != null)
{
rtb = starting.Controls[0] as RichTextBox;
}
rtb.TextChanged += new EventHandler(txtBox_TextChanged);
rtb.MouseClick += new MouseEventHandler(rtbh_MouseClick);
//rtb.Select(rtb.Text.Length, 0);
rtb.Font = new Font(rtb.Font.FontFamily, 12);
rtb.Select(rtb.Text.Length, 0);
return rtb;
}
The class the user gave you inherits from RichTextBox - so when adding textboxes to your text editor, add this custom class. And for your function of finding textboxes, use the custom control. So change the above function to this:
public HighlightableRTB GetRichTextBox()
{
HighlightableRTB rtb = null;
TabPage starting = tabControl1.SelectedTab;
if (starting != null)
{
rtb = starting.Controls[0] as HighlightableRTB;
}
if (rtb != null)
{
rtb.TextChanged += new EventHandler(txtBox_TextChanged);
rtb.MouseClick += new MouseEventHandler(rtbh_MouseClick);
//rtb.Select(rtb.Text.Length, 0);
rtb.Font = new Font(rtb.Font.FontFamily, 12);
rtb.Select(rtb.Text.Length, 0);
}
return rtb;
}
The actual adding of the custom textbox should probably look something like this:
TabPage tabPage = new TabPage("Test");
tabPage.Name = "Test";
tabControl1.TabPages.Add(tabPage);
HighlightableRTB customTextBox = new HighlightableRTB();
tabControl1.TabPages["Test"].Controls.Add(customTextBox);

C# Get text from a textbox that is made at runtime

Hello I am making a program that has 2 textboxes and 2 buttons
When I press the add button then it will make 2 new textboxes using this code :
private void ADD_ROW_Click(object sender, EventArgs e)
{
//Make the NEW_TEXTBOX_1
HOW_FAR += 1;
TextBox NEW_TEXTBOX_1 = new TextBox();
NEW_TEXTBOX_1.Name = "NAME_TEXTBOX_" + HOW_FAR.ToString();
//Set NEW_TEXTBOX_1 font
NEW_TEXTBOX_1.Font = new Font("Segoe Print", 9);
NEW_TEXTBOX_1.Font = new Font(NEW_TEXTBOX_1.Font, FontStyle.Bold);
//Set pos and size and then create it.
NEW_TEXTBOX_1.Location = new System.Drawing.Point(16, 71 + (35 * HOW_FAR));
NEW_TEXTBOX_1.Size = new System.Drawing.Size(178, 29);
this.Controls.Add(NEW_TEXTBOX_1);
//Make the PRICE_TEXTBOX_
TextBox NEW_TEXTBOX_2 = new TextBox();
NEW_TEXTBOX_2.Name = "PRICE_TEXTBOX_" + HOW_FAR.ToString();
//Set NEW_TEXTBOX font
NEW_TEXTBOX_2.Font = new Font("Segoe Print", 9);
NEW_TEXTBOX_2.Font = new Font(NEW_TEXTBOX_2.Font, FontStyle.Bold);
//Set pos and size and then create it.
NEW_TEXTBOX_2.Location = new System.Drawing.Point(200, 71 + (35 * HOW_FAR));
NEW_TEXTBOX_2.Size = new System.Drawing.Size(89, 29);
this.Controls.Add(NEW_TEXTBOX_2);
//Change pos of the add button
ADD_ROW.Location = new System.Drawing.Point(295, 71 + (35 * HOW_FAR));
this.Height = 349 + (35 * HOW_FAR);
this.Width = 352;
}
This works very well but now I want to get the text from a newly made textbox back how do I do this?
This doesn't work because it says : NAME_TEXTBOX_1 Does not exist in the current context.
private void button2_Click(object sender, EventArgs e)
{
string tmpStr = NAME_TEXTBOX_1.Text;
}
You need to move the variable declaration outside of the ADD_ROW_Click event handler so that it's accessible outside that block;
TextBox NEW_TEXTBOX_1;
private void ADD_ROW_Click(object sender, EventArgs e)
{
//Make the NEW_TEXTBOX_1
HOW_FAR += 1;
NEW_TEXTBOX_1 = new TextBox(); //remove "TextBox" since we declared it above
NEW_TEXTBOX_1.Name = "NAME_TEXTBOX_" + HOW_FAR.ToString();
//...
The alternative, and possibly better depending on the number of textboxes, is to add each TextBox you create into a List. You can then iterate that List from and find the TextBox you want. For example
List<TextBox> allTextBoxes = new List<TextBox>();
private void ADD_ROW_Click(object sender, EventArgs e)
{
//Make the NEW_TEXTBOX_1
HOW_FAR += 1;
TextBox NEW_TEXTBOX_1 = new TextBox();
//...fill out the properties
//add an identifier
NEW_TEXTBOX_1.Tag = 1;
allTextBoxes.Add(NEW_TEXTBOX_1);
}
Then when you want a particular TextBox
private void button2_Click(object sender, EventArgs e)
{
TextBox textBox1 = allTextBoxes.Where(x => x.Tag == 1).FirstOrDefault();
string tmpStr = "";
if(textBox1 != null)
tmpStr = textBox1.Text;
}
Alternatively, and especially if you're going to have a lot of TextBoxes, you could store them in a Dictionary as Corak suggested in the comments.
you're declaring NAME_TEXTBOX_1 within the ADD_ROW_Click method, which is why it isn't available within the button2_Cick method.
You can declare the textbox at the class level to access it in both places.
(You should work on renaming your variables too - e.g. TextBoxPrice)
One simple solution:
Make a private field called "NEW_TB" for example.
In your button2_Click(..) { string tmpStr = NEW_TB.Text; }
Add in your ADD_ROW_Click(..) method NEW_TB = NAME_TEXTBOX_1;
If I understood your question right, this should work.
Make global your textboxes:
TextBox NEW_TEXTBOX_1;
then initiate them in your method:
NEW_TEXTBOX_1 = new TextBox();
OMG Never mind sorry guys I found a good way :D
var text = (TextBox)this.Controls.Find("PRICE_TEXTBOX_1", true)[0];
text.Text = "PRO!";
This works pretty well :)

Adding UI components dynamically to my Winform

I'm trying to create components on the fly, so, I know how to make this, but, how can I access this component on the fly?
For example:
public Form1
{
Label label1 = new Label();
label1.AutoSize = true;
label1.Location = new System.Drawing.Point(e.X, e.Y);
label1.Name = string.Format("label{0}", labelsCount.ToString());
label1.Size = new System.Drawing.Size(35, 13);
label1.TabIndex = 2;
label1.Text = string.Format("Label -> {0}", labelsCount.ToString());
label1.Click += new System.EventHandler(this.label1_Click);
this.Controls.Add(label1);
label1.BringToFront();
label1.Show();
labelsCount++;
}
When I click on the label, I want to get the label's information (like position, text and name)
How I can do this? Or, what is the best way to do this?
And, to access the component based on position of the panel, inside of form, how I can do this?
Sender of event is your lablel. Simply cast sender object to Label type:
void label1_Click(object sender, EventArgs e)
{
Label label = (Label)sender;
// use
// label.Name
// label.Location
}

Categories