I would like to have direct access to the text inside a textbox on another form, so I added a public variable _txt to a form and added an event like so:
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
_txt = richTextBox1.Text;
}
But the form is loaded like this:
public FrmTextChild(string text)
{
InitializeComponent();
_txt = text;
richTextBox1.Text = _txt;
Text = "Untitled.txt";
}
Is there a better way to directly link the two?
You could use a property instead to read directly from your TextBox. That way you don't need an extra variable at all.
public string Text
{
get
{
return richTextBox1.Text;
}
}
Add a setter if you also want to be able to change the text.
I don't think you should ever have forms reference each other's controls: when you change the lay out of one you will have to rewrite the code for the other. It is much better IMHO to store shared values in a separate class and have both forms reference that. Like so:
public class DataContainer
{
public string SomeData{get;set;}
}
public class Form1:Form
{
private DataContainer _container;
public Form1(DataContainer container)
{
_container=container;
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
_container.SomeData = richTextBox1.Text;
}
private void SpawnForm2()
{
var form2=new Form2(_container);
form2.Show();
}
public class Form2:Form
{
private DataContainer _container;
public Form2(DataContainer container)
{
_container=container;
}
}
Another way to do it would be setting the Modifiers property for the TextBox (or any other control you want to access) to Protected Internal and then open the second form, the Owner being the first form.
This way, you can later on access the control and its properties with something like this:
((Form1)this.Owner).textBox1.Text = "This is a message from the second form";
Related
I have the following question. I am using C# .NET, and I want to save a value in numericupdown box after I close my form. In my aplication I have in total 2 forms, so I want to save the value I enter in the second one, and after I open it again I want to see the last value. In my case the numericupdown value is empty after I open the second form again.
I was thinking about something like this:
namespace Project2
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
decimal a = numericUpDown1.Value;
label2.Text = "N: " + a;
}
}
}
But is still empty after I open it again.
You can create a class which provides set/get for a NumericUpDown control in this case using the following.
public sealed class Setting
{
private static readonly Lazy<Setting> Lazy =
new Lazy<Setting>(() => new Setting());
public static Setting Instance => Lazy.Value;
public decimal NumericUpDownValue { get; set; }
}
In the child form, OnShown set Value property to Settings.NumericUpDownValue then OnClosing remember the value.
public partial class ChildForm : Form
{
public ChildForm()
{
InitializeComponent();
Shown += (sender, args) =>
numericUpDown1.DataBindings.Add("Value", Setting.Instance,
nameof(Setting.NumericUpDownValue));
Closing += (sender, args) =>
Setting.Instance.NumericUpDownValue = numericUpDown1.Value;
}
}
The code above, specifically Settings class is known as the Singleton Pattern which you can learn more about in Implementing the Singleton Pattern in C#.
You can use static variable to store last updated value and with the reference of class name you can use it where ever you want.
From MSDN: Two common uses of static fields are to keep a count of the number of
objects that have been instantiated, or to store a value that must
be shared among all instances.
Like,
namespace Project2
{
public partial class Form2 : Form
{
public static decimal lastNumericUpDownValue = 0;
public Form2()
{
//For example: thiw will print lastest saved Numeric updown value.
//For the first time, it will print 0
Console.WriteLine(Form2.lastNumericUpDownValue);
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Assign value to lastNumericUpDownValue variable. Look at how it is used.
Form2.lastNumericUpDownValue = numericUpDown1.Value;
}
}
}
Suppose i have created a WPF form having one text box. i am calling that form inside another wpf window's gridpanel and after entering value inside the textbox, i am clicking on submit button. After button click, i need to get that value and save it in string form inside my current class. My logic is something like this.
For getting the from inside my current window:-
void SelectedClick(object sender, RoutedPropertyChangedEventArgs<object> e)
{
selectedItem.ContextMenu = VcontextMenu;
VcontextMenu.Items.Add(VmenuItem1);
VmenuItem1.Click += AddValidation;
details();
}
void AddValidation(object sender, RoutedEventArgs e)
{
ValidationForm obj = new ValidationForm();
ProcessGrid.Content = obj.VForm;
}
Now i want to store the value of my textbox inside a string. For that i have used following code:-
public void details()
{
ValidationForm obj = new ValidationForm();
string str = obj.s.ToString();
}
My ValidationForm Code:-
public partial class ValidationForm : UserControl
{
public string s { get; set; }
public ValidationForm()
{
InitializeComponent();
}
public void XSave_Click(object sender, RoutedEventArgs e)
{
s = TextValidationName.Text;
}
}
but instead of opening the form, the control is going to obj.s.ToString() and showing error as "Object reference not set to an instance of an object." Please help. Thanks.
The issue is caused since the string s in your ValidationForm class is not assigned. It is probably caused since the XSave_Click() method is not being called.
Ensure that you properly assign the value to s before you try to get value from it.
I'm wondering about why can I access text from, for example, a combobox from outside the main class. But I can't add items to it.. the modifier of my combobox is set to public
public class ImageManager : mainFrame // Where my components are located
{
public ImageManager()
{
}
public void getText()
{
Console.WriteLine(comboBox.Text); //Will perfectly retrieve the text from it
}
public void setItem()
{
comboBox.Items.Add("Items"); //Does absolutely nothing and doesn't show error
}
}
Thanks for help !
What if your setItem() populated a ComboboxItem and added it instead of just text?
public void setItem()
{
ComboboxItem addMe = new ComboboxItem();
addMe.Text = "your text here";
addMe.Value = 1234; // make a relevant value
comboBox.Item.Add(addMe);
}
I see you got it working, great. But just in case your still scratching your head...
private void Form1_Load(object sender, EventArgs e)
{
ImageManager im = new ImageManager();
im.Show();
im.setItem();
}
ImageManager inherits from Form2 which has the comboBox. Seemed to work fine. comboBox got populated.
I've got code and i know I'm 99% of the way there. C# coding in MS VS2008.
Basically I have a form that has 4 radio buttons and a Continue button. the user clicks one of the radio buttons and clicks continue, and this all works fine.
However, I want to use the value entered by the user (i.e. if they click the first button, I want a variable equal to 1, 2nd button equals 2 and so on). I tried doing this in various points but the only place I can get it to run is in the private void btnOkClick line, which means I can use the values outside this void, which is what I really want.
I've tried playing around with setting some enums and such (commented out in the code below), but I can't quite get it. I know I must be close but my novice-ness is truly showing as I keep reading posts and can't quite grasp it.
In short, I want to be able to have other classes in my VS2008 project be able to reference whatever value the user selected in the initial form.
namespace AmortClient
{
public partial class frmLoadACTFCST : Form
{
public frmLoadACTFCST()
{
InitializeComponent();
//set the parent of the form to the container
//this.MdiParent = parent;
}
//public enum ACTFCST
//{
// ACT = 1,
// FCST = 2,
// PLAN = 3,
// FiveYearPlan2012=4
//}
//private ACTFCST _actfcst = ACTFCST.ACT;
//public ACTFCST actfcst
//{
// get { return _actfcst; }
// set { _actfcst = value; }
//}
private void frmLoadACTFCST_Load(object sender, EventArgs e)
{
}
private void groupBox1_Enter(object sender, EventArgs e)
{
}
private void btnActual_CheckedChanged(object sender, EventArgs e)
{
}
private void btnForecast_CheckedChanged(object sender, EventArgs e)
{
}
private void btnPlan_CheckedChanged(object sender, EventArgs e)
{
}
private void btn5YrPlan2012_CheckedChanged(object sender, EventArgs e)
{
}
private void btnContinue_Click(object sender, EventArgs e)
{
string ACTFCSTtext = "";
int dataTypeKey = 0;
if (btnActual.Checked)
{
ACTFCSTtext = btnActual.Text;
dataTypeKey = 1;
}
else if (btnForecast.Checked)
{
ACTFCSTtext = btnForecast.Text;
dataTypeKey = 2;
}
else if (btnPlan.Checked)
{
ACTFCSTtext = btnPlan.Text;
dataTypeKey = 3;
}
else if (btn5YrPlan2012.Checked)
{
ACTFCSTtext = btn5YrPlan2012.Text;
dataTypeKey = 4;
}
string msg = "";
msg = ACTFCSTtext + " " + dataTypeKey;
//btn5YrPlan2012
MessageBox.Show(msg);
Close();
}
}
}
Your dataTypeKey and ACTFCSTtext variables need to be declared as instance variables for your Form object if you want to access them from any other methods within your form. If you want to use them with some other form, you can pass them either as constructor arguments, or set some properties of said other form.
So you'd declare them just after the class declaration if you want them to be instance variables. They should still be private, meaning they can only be accessed from within your frmLoadACTFCST class.
public partial class frmLoadACTFCST : Form
{
private string ACTFCSTtext = "";
private int dataTypeKey = 0;
...
EDIT: if you want to access variables from one object in a different object (or static class), your options are as follows...
1) Declare your variables as public instance variables (same as shown above but public; these are known as Properties when you give them getter and setter methods). Your class that needs access to these variables would need to have a reference to the class that owns the variables.
Example:
FormA has a public property named SomeString.
FormB needs to access SomeString.
FormB needs a reference to FormA, and would access the variable as...
formAReference.SomeString
2) Pass the values of the variables as arguments to some method for the class that needs access.
Example:
FormA has a private instance variable named SomeString.
FormB needs access to SomeString.
If FormA instantiates FormB, it can pass the value of SomeString to FormB's constructor...
//From within FormA's code
FormB formB = new FormB(SomeString);
//FormB's constructor
public FormB(string someString)
{
this.someString = someString;
}
Maybe there is a smarter way to do it.
public partial class frmLoadACTFCST : Form
{
public frmLoadACTFCST()
{
InitializeComponent();
actfcst = ACTFCST.ACT;
btnActual.Tag = ACTFCST.ACT;
btnActual.Checked = true;
btnForecast.Tag = ACTFCST.FCST;
btnPlan.Tag = ACTFSCT.PLAN;
btn5YrPlan2012.Tag = ACTFCST.FiveYearPlan2012;
}
public enum ACTFCST
{
ACT = 1,
FCST = 2,
PLAN = 3,
FiveYearPlan2012=4
}
public static ACTFCST actfcst { get; private set; }
private void CheckedChanged(object sender, EventArgs e)
{
// All the buttons uses this Click-event.
actfcst = (sender as Button).Tag as ACTFCST;
}
private void btnContinue_Click(object sender, EventArgs e)
{
MessageBox.Show(actfcst.ToString());
Close();
}
}
The point is that all the buttons calls CheckedChanged when clicked.
Using a static means that others can access the value using something like this:
frmLoadACTFCST.ACTFCST value = frmLoadACTFCST.actfcst;
// Do something based on value.
I hope this helps you in yoyr quest.
If you select a control in design view, the properties window contains an item named "Modifiers". You can make the control public here.
A better way would be to create a new public property on your form that yields the value of the currently selected radio button.
I'm completely new to GUI programming and need a little help with a list of pictureboxes.
The idea is that I have a list of pictureboxes. When a user clicks on one I want to (for example) change the BorderStyle property of the one selected to be Fixed3D, but change the remaining collection borders to FixedSingle (or something like that). What's the proper way to do something like this? I guess the bigger picture is how do I get a method of one class to call a method of another without having any information about it?
class myPicture
{
private int _pictureNumber;
private PictureBox _box;
public myPicture(int order)
{
_box = new List<PictureBox>();
_box.Click += new System.EventHandler(box_click);
_pictureNumber = order;
}
public void setBorderStyle(BorderStyle bs)
{
_box.BorderStyle = bs;
}
public void box_click(object sender, EventArgs e)
{
//here I'd like to call the set_borders from myPicturesContainer, but I don't know or have any knowledge of the instantiation
}
}
class myPicturesContainer
{
private List<myPicture> _myPictures;
//constructor and other code omitted, not really needed...
public void set_borders(int i)
{
foreach(myPicture mp in _MyPictures)
mp.setBorderStyle(BorderStyle.FixedSingle);
if(i>0 && _MyPictures.Count>=i)
_MyPictures[i].setBorderStyle(BorderStyle.Fixed3d);
}
}
You will need to create a Clicked event in your myPicture class and raise that event when it is clicked. Then you will need to attach to this event in your myPicturesContainer for each instance of myPicture that you have.
Here is a very simple example of what I mean:
class myPicture
{
public event Action<Int32> Clicked = delegate { };
private int _pictureNumber;
public void box_click(object sender, EventArgs e)
{
this.Clicked(this._pictureNumber);
}
}
class myPicturesContainer
{
private List<myPicture> _myPictures;
public void set_borders(int i)
{
foreach (myPicture mp in _myPictures)
{
mp.Clicked += pictureClick;
}
}
void pictureClick(Int32 pictureId)
{
// This method will be called and the pictureId
// of the clicked picture will be passed in
}
}