I am wondering how to return the value of a class property with the input of a textbox? i.e. the input in the nameTextBox would go to the Name property of a Pet class, the breedTextBox would be the Breed property, etc.
Using C# windows form.
Pet pet = new Pet();
pet.Name = nameTextBox.Text;
etc.
If your question is how to get this code executed then either have an "update" Button, and in its Click event handler run this code, or subscribe to the Textbox's TextChanged event and do it there. (You can also use binding, a bit more complicated. See here.)
This logic can be accomplished by handling the TextChanged event of your TextBox instances. Given the current Pet instance m_Pet (allocated within your class as a member, for example):
private Pet m_Pet = new Pet();
and the events subscription in the InitializeComponent method of the form:
m_TextBoxName = new TextBox();
m_TextBoxName.TextChanged += TextBoxName_TextChanged;
here is how you can accomplish this:
private void TextBoxName_TextChanged(Object sender, EventArgs e)
{
m_Pet.Name = m_TextBoxName.Text;
}
And the same can be performed for as many properties as you want:
private void TextBoxBreed_TextChanged(Object sender, EventArgs e)
{
m_Pet.Breed = m_TextBoxBreed.Text;
}
private void TextBoxType_TextChanged(Object sender, EventArgs e)
{
m_Pet.Type = m_TextBoxType.Text;
}
Related
So this is a fairly straightforward thing, and I am just curious if there is a better way to do it to save lines of code. For class we are making a teletype machine. Basically there is a textbox, and a series of buttons A-Z and 0-9. When you click the button it adds the corresponding letter/number to the textbox. When you click send, it adds the contents of the textbox to a label and resets the textbox. Everything works and it only took a few minutes to build. However there is a mess of redundant lines and I was curious if there is a way to clean up the code with a method.
This is my current code.
private void btn_A_Click(object sender, EventArgs e)
{
box_UserInput.Text = box_UserInput.Text + "A";
}
As you can see, it is very simplistic and straight forward. Click A, and "A" gets added to the textbox. However the Text property of the button is also just "A" and I want to know if there is a way to just copy the text property of that button and add it to the textbox string.
Something like this, except with a universal approach where instead of having to specify btn_A it just inherits which button to copy based on the button clicked. That way I can use the same line of code on every button.
private void btn_A_Click(object sender, EventArgs e)
{
box_UserInput.Text = box_UserInput.Text + btn_A.Text;
}
You can use this which is more universal as the Control class contains the Text property. Also, using the best practice $"".
private void btn_A_Click(object sender, EventArgs e)
{
box_UserInput.Text = $"{box_UserInput.Text}{((Control)sender).Text}";
}
You can also assign the same event to each button. Create an event, say addControlTextOnClick and assign the same event to each button.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void addControlTextOnClick(object sender, EventArgs e)
{
box_UserInput.Text = $"{box_UserInput.Text}{((Control)sender).Text}";
}
}
You can even shorten this more using this C# construct:
private void addControlTextOnClick(object sender, EventArgs e) =>
box_UserInput.Text = $"{box_UserInput.Text}{((Control)sender).Text}";
I dynamically create controls and I'd like to be able to use them outside of the context.
For example a dynamically created label :
i = 0;
while (readerBE.Read())
{
Label labelBE = new Label();
labelBE.Name = "labelBE" + i;
labelBE.Text = readerBE["codeArticleComposant"].ToString();
labelBE.Cursor = Cursors.Hand;
labelBE.Click += new EventHandler(this.labelBE_Click);
i++;
}
And when I try to use the OnClick event to retrieve a value like this :
private void labelBE_Click(object sender, EventArgs e)
{
Console.WriteLine(labelBE.Text);
}
labelBE does not exist in the current context.
You can cast the sender argument:
private void labelBE_Click(object sender, EventArgs e)
{
Label labelBE = (Label) sender;
Console.WriteLine(labelBE.Text);
}
But one thing, you have a while-loop and you always create this Label and you never add it to any container control (like GroupBox, Panel or Form). So you would never create multiple and either the while-loop is wrong and should be replaced with an if or you should add the labels to a collection or parent control (well, you should do that anyway).
You can use the sender object that generated the click :
private void labelBE_Click(object sender, EventArgs e)
{
Console.WriteLine(((Label)sender).Text);
}
However I suggest you read more about Variable scope.
Your problem is that you create a variable inside a method, so this variable is no more accessible once you leave it.
I'm trying to use this function:
private void IDCustTextBox_LostFocus(object sender, System.EventArgs e)
{
if (CustName.Text == "abc")
MessageBox.Show("Error");
}
When I type abc in CustName textbox, and then leave the textbox, I dont get any message. In the textbox properties I can see that "textbox.Changed" is using the event LostFocus.
How can I get this to show the Error message above?
There is no LostFocus event for textbox in property Window,if you want to use this then you must need to add event handler, there is textbox leave event in property window, that could be used as below:
private void textBox1_Leave(object sender, EventArgs e)
{
// do your stuff
}
for adding event handler you need to write the following:
textBox1.LostFocus += new EventHandler(textBox1_LostFocus);
then you can use it as below:
private void textBox1_LostFocus(object sender, EventArgs e)
{
// do your stuff
}
You will need to let the field know that there is a handler for the event LostFocus
Since this is not part of the properties window you will have attach the handler as such
CustTextBox.LostFocus += new EventHandler(IDCustTextBox_LostFocus);
I want to be able to right click on an image and for there to be a menu show up. When I then click on one of the items I want it to point to a class:
private void link1add_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("Add", HandleContextMenuAdd);
cm.MenuItems.Add("Remove", HandleContextMenuRemove);
link1add.ContextMenu = cm;
}
}
private void HandleContextMenuAdd(object sender, EventArgs e)
{
MessageBox.Show("Adding");
}
private void HandleContextMenuRemove(object sender, EventArgs e)
{
MessageBox.Show("Removing");
}
Code edited since first posted.
Thanks all for your help.
What about a lambda expression?
cm.MenuItems.Add("Item 2", (_, __) => {
if (...) ReadDocument();
});
or
cm.MenuItems.Add("Item 2", (_, __) => { this.myClassInstance.DoSomething(); });
Alternatively, you can create a method with the signature of the expected event handler:
cm.MenuItems.Add("Item 2", HandleContextMenuClick);
private void HandleContextMenuClick(object sender, EventArgs e)
{
if (...) ReadDocument();
}
That method doesn't need to be in the same class (you can write this.myClassInstance.HandleContextMenuclick for example). But I would hide the implementation detail from other classes to avoid unnecessary coupling.
Pattern for your own code after this:
public class ReadDocumentEventArgs : EventArgs
{
public string ImageInfo { get; set; }
}
public void ReadDocument(object sender, ReadDocumentEventArgs ea)
{
// do whatever you need to do
MessageBox.Show(ea.ImageInfo); // example
}
private void link1add_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
PictureBox imageCtrl = sender as PictureBox;
// get the information you need to get from your control to identify it
string imgInfo = "Hello, World!"; // example
ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("Item 1");
cm.MenuItems.Add("Item 2",
(EventHandler)((s, rde) =>
{ ReadDocument(s, new ReadDocumentEventArgs()
{ ImageInfo = imgInfo });
}));
link1add.ContextMenu = cm;
}
}
In your MouseDown over your image you can create a menu item using the code I supplied above that will call an event handler called ReadDocument. Notice that there is a ReadDocumentEventArgs class that you can customize to contain the necessary properties that will help you identify which image you have clicked on.
So, in the example I have above one of the first things that happens in MouseDown is that you get the instance of image control (I assume it's a Picture Box, but you can cast it to whatever it really is).
At that point, you can then get a file name or whatever from your image that identifies it from the other controls on your form.
Next, when creating a context menu item, it tells the menu item to call ReadDocument but passes in the special data just taken from the image control.
In the ReadDocument method, you can then do whatever you need to do. In my example, I simply throw up a MessageBox to show you what data you passed in.
What you will want is to put another event handler and call your readdocument method.
I have a windows form application which consists of a bunch of controls, but more specifically, two textBoxes. One of them is read only. The read only textBox value is supposed to be the same as the textBox that the user can type into.
So if the user types "Hello World" into textBox A, the value in textBox B should be automatically updated to "Hello World".
How do I go about doing this? I know I just need to set the text values, I'm just not sure where I place the code to get it done automatically rather than executed when a button is click or something along those lines.
TextChanged event:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Text = textBox1.Text;
}
It sounds like you want something like:
writableTextBox.TextChanged += delegate {
readonlyTextBox.Text = writableTextBox.Text;
};
In other words, whenever the text in one textbox changes, update the other. This uses the Control.TextChanged event.
If you want textBoxB to be updated as soon as the text of textBoxA is changed (i.e immediately after the user press a key in textBoxA) the event is TextChanged:
this.textBoxA.TextChanged += new System.EventHandler(this.textBoxA_TextChanged);
private void textBoxA_TextChanged(object sender, EventArgs e)
{
textBoxB.Text = textBoxA.Text;
}
If you prefer to update the text in textBoxB only after the user has finished to edit textBoxA, you should use the Leave event:
this.textBoxA.Leave += new System.EventHandler(this.textBoxA_Leave);
private void textBoxA_Leave(object sender, EventArgs e)
{
textBoxB.Text = textBoxA.Text;
}
This should do what you need:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Text = textBox1.Text;
}
Even shorter (better?) than the event approach is using winform's databinding. Just use this right after the InitializeComponents call:
readonlyTextBox.DataBindings.Add("Text", writableTextBox, "Text");