Extending ref keyword to another variable - c#

I'm developing wpf application.
I'm trying to pass object by reference using ref keyword and then pass it to another variable in constructor to change it later. But when I change the variable to which I passed the reference in constructor varaible doesn't change outside scope.
To explain, first I create variable and pass it to another window's constructor.
private void LocatonEditButton_Click(object sender, RoutedEventArgs e)
{
var location = new Location(SelectedLocation.Name, SelectedLocation.X, SelectedLocation.Y, SelectedLocation.Update);
//Creating object
var result = new EditWindow(ref location,true).ShowDialog();
//And passing it to another window with ref
}
Here I assign variable to InitialLocation, if I try to change it here it works on outside variable.
public partial class EditWindow : Window
{
public EditWindow(ref Location location, bool isEdit)
{
InitializeComponent();
InitialLocation = location;
//InitialLocation = ref location; //This is what I want my code to do
location.Name = "new"; //this changes varaiable outside scope
}
private Location InitialLocation;
Here I change InitialLocation but change doesn't persits outside the scope.
private void ConfirmButton_Click(object sender, RoutedEventArgs e)
{
InitialLocation = new Location(CurrentLocation.Name, CurrentLocation.X, CurrentLocation.Y, InitialLocation.Update);
//But this doesn't change varaible outside scope
this.Close();
}
I want to keep object that was passed with ref until the window I passed it to is disposed.
Is it possible to do without waiting for closed event?

I suggest to declare InitialLocation as public property.
public partial class EditWindow : Window
{
public EditWindow(Location location, bool isEdit)
{
InitializeComponent();
InitialLocation = location;
location.Name = "new";
}
public Location InitialLocation { get; set; }
private void ConfirmButton_Click(object sender, RoutedEventArgs e)
{
InitialLocation = new Location(CurrentLocation.Name, CurrentLocation.X, CurrentLocation.Y, InitialLocation.Update);
this.Close();
}
}
after editing read the value of that property:
private void LocatonEditButton_Click(object sender, RoutedEventArgs e)
{
var location = new Location(SelectedLocation.Name, SelectedLocation.X, SelectedLocation.Y, SelectedLocation.Update);
var editWindow = new EditWindow(location, true);
var result = editWindow.ShowDialog();
var changedLocation = editWindow.InitialLocation;
}

Related

I want to link two variables by ref so as when I update one variable the other updates also

I want to assign one variable to another by reference so as when one variable updates so does the other.
I have a series of variables that I need to update based on something that a piece of hardware I am connected to is doing. I have set up an object array and am assigning each of my variables to an index in the object array. It is the object array that gets updated but when this happens I want the property setter for my original variable to fire so as I can do something. The reason for the object array is so as I can iterate through it in a loop and because my original variables can be of different types. I have shown an overly simplified version of what I am trying to do below, I hope it makes sense.
Edit: Just to note that the items in the testVars array are being updated elsewhere, I have just shown a simplified version of what I am trying to do below.
public partial class Form1 : Form
{
private bool _test0 = false;
private int _test1 = 0;
public object[] testVars = new object[2];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
testVars[0] = test0;
testVars[1] = test1;
}
public bool test0
{
get
{
return _test0;
}
set
{
_test0 = value;
UpdateTest0();
}
}
private void UpdateTest0()
{
bool NewTest0 = _test0;
}
public int test1
{
get
{
return _test1;
}
set
{
_test1 = value;
UpdateTest1();
}
}
private void UpdateTest1()
{
int NewTest1 = _test1;
}
}
One solution I thought might work for me was to use pointers but because the variable declaration and pointer creation must be in different scope in my application this will not work. Also everything I have read on forums has suggested that pointers should not be used.
# Michael Ceber, many thanks for the prompt response. I think I understand what you mean and have updated my example code accordingly but it still does not behave as I want. My updated code is as follows
namespace VariableLinks
{
public partial class Form1 : Form
{
private bool _test0 = false;
private int _test1 = 0;
public ObjectX[] testVars = new ObjectX[2];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
testVars[0] = new ObjectX();
testVars[0].val = test0;
testVars[1] = new ObjectX();
testVars[1].val = test1;
}
public bool test0
{
get
{
return _test0;
}
set
{
_test0 = value;
UpdateTest0();
}
}
private void UpdateTest0()
{
bool NewTest0 = _test0;
}
public int test1
{
get
{
return _test1;
}
set
{
_test1 = value;
UpdateTest1();
}
}
private void UpdateTest1()
{
int NewTest1 = _test1;
}
private void button1_Click(object sender, EventArgs e)
{
testVars[0].val = true;
}
}
public class ObjectX : object
{
public object val = new object();
}
}
Now when my button click event fires and updates testVars[0].val I expect the setter for test0 to fire but it doesn't. I assume I have misunderstood what you meant?
If you store objects or reference types to objects in your array, i.e not value types like int, bool etc, which contain the values, then this will help.
e.g if your object 'objectx' has a property called value then objectx.value can store such a value.
Then you can set any variables you like to this objectx and whenever you update the value of objectx.value all variables will pickup the change, as they are all pointing to the same object...
So in your example
testVars[0] = test0;
testVars[1] = test1;
this would become
testVars[0].value = test0;
testVars[1].value = test1;
maybe to achieve this
public object[] testVars = new object[2];
should become
public ObjectX[] testVars = new ObjectX[2];
and add the single public property 'value' to this ObjectX class...
Hope that makes sense!

Issues with calling method from another form

I've found some good posts about using methods in other forms and tried to implement them in my code, but I'm getting a null object error (specifically, the frmAddMaterials object is null). Code compiles fine, error occurs when trying to use the create materials button on the second form.
My first form has an array to hold material information. When the user clicks a link on this first form, they are prompted with a second form where they can enter custom material information in the event that the material they are interested in using is not on designed in. Upon clicking "Add material" on form 2, I would like the RefreshMaterials() method on the first form to run, which creates a new entry in the array based on information from the second form.
Form1:
public partial class frmSnapFitMain : Form
{
public frmMat frmAddMaterials;
public Materials[] material = new Materials[20];
Image[] problemtype = new Image[7];
private void linkLabel1_LinkClicked_1(object sender,LinkLabelLinkClickedEventArgs e)
{
frmMat frmAddMaterials = new frmMat(this);
frmAddMaterials.Show();
}
public void RefreshMaterials()
{
material[Materials.MaterialCount] = new Materials(frmAddMaterials.txtName.Text, Double.Parse(frmAddMaterials.txtFlex.Text), Double.Parse(frmAddMaterials.txtFriction.Text), Double.Parse(frmAddMaterials.txtStrain.Text)); //little m, materials here is for specific instance
cboxMatSelect.Items.Add(frmAddMaterials.txtName.Text);
frmAddMaterials.txtName.Text = ""; //reset fields
frmAddMaterials.txtFlex.Text = "";
frmAddMaterials.txtFriction.Text = "";
frmAddMaterials.txtStrain.Text = "";
}
}
Form 2:
public partial class frmMat : Form
{
private readonly frmSnapFitMain _form1;
public frmMat(frmSnapFitMain Form1)
{
InitializeComponent();
this._form1 = Form1;
}
public void btnCreate_Click(object sender, EventArgs e)
{
this._form1.RefreshMaterials();
this.Close();
}
public void frmMat_Load(object sender, EventArgs e)
{
}
}
In the linkLabel1_LinkClicked_1 method you declare a new instance of frmMat. This instance happens to have the same name of the global variable but it is a local one that disappears when you exit from the method.
private void linkLabel1_LinkClicked_1(object sender,LinkLabelLinkClickedEventArgs e)
{
// This is not the global variable frmAddMaterials.
// It is a local one to this method
frmMat frmAddMaterials = new frmMat(this);
frmAddMaterials.Show();
}
Of course this means that in your RefreshMaterials you use the global variable that has never been initialized
You just need to remove the declaration of a local variable and initialize the global one
private void linkLabel1_LinkClicked_1(object sender,LinkLabelLinkClickedEventArgs e)
{
// This initializes the global variable
frmAddMaterials = new frmMat(this);
frmAddMaterials.Show();
}
Said that it is always a good practice to use a 'defensive programming attitude' when using global variables and test if the variable has been correctly initialized.
public void RefreshMaterials()
{
if(frmAddMaterials != null)
{
material[Materials.MaterialCount] = new Materials(.....)
cboxMatSelect.Items.Add(frmAddMaterials.txtName.Text);
frmAddMaterials.txtName.Text = ""; //reset fields
frmAddMaterials.txtFlex.Text = "";
frmAddMaterials.txtFriction.Text = "";
frmAddMaterials.txtStrain.Text = "";
}
}
I also suggest to subscribe to the FormClosing event of frmAddMaterials to set your instance to null when the form closes
private void linkLabel1_LinkClicked_1(object sender,LinkLabelLinkClickedEventArgs e)
{
if(frmAddMaterials != null)
{
frmAddMaterials = new frmMat(this);
frmAddMaterials.Show();
frmAddMaterials.FormClosing += frmMaterialsClosing;
}
}
private void frmMaterialsClosing(object sender, CancelEventArgs e)
{
frmAddMaterials = null;
}
This allows you to restart the 'cycle' because when you click again the linklabel your global variable is null and you could reinitialize it to the new instance created in the linklabel click event handler.

How to pass data between WPF forms

I need help passing data from one WPF form to another. I have a main window with two other windows that will prompt the user for information. I want to end up with all the information in the first form so that I can store the data later on. The second form must return the Reservation and Room information when you click the OK button on the second form. The third form must return the Person information when you click OK.
public partial class MainWindow : Window
{
private string message;
public MainWindow()
{
InitializeComponent();
}
protected void Exit_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
protected void Create_Reservation_Click(object sender, RoutedEventArgs e)
{
Reservation PersonReservation = new Reservation();//Create a reservation instance
Room PersonRoom = new Room(); //Create an instance of a room
Person myPerson = new Person();//Create an instance of a person
CreateResRoom createReservationRoom = new CreateResRoom();//Create a instance of the CreateReservation WPF Form
createReservationRoom.Show();
Here it is supposed to set the room, reservation and person instance that I created equil to their corresponding instances in the CreateResRoom class.
I think the problem lies here, because it keeps continuing before it opens the CreateResRoom form.
PersonRoom = createReservationRoom.myRoom;
PersonReservation = createReservationRoom.myReservation;
}
}
That was my first class, the second and third will follow.
public partial class CreateResRoom : Window
{
Person myPerson;
public CreateResRoom()
{
InitializeComponent();
myReservation = new Reservation();
myRoom = new Room();
myPerson = new Person();
}
public Room myRoom
{
get;
set;
}
public Reservation myReservation
{
get;
set;
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
private void btnOk_Click(object sender, RoutedEventArgs e)
{
myRoom.RoomBeds = txtHeadCount.Text;
myRoom.RoomNumber = 1;
myRoom.RoomPrice = 20;
myRoom.RoomType = cboRoomType.Text;
myReservation.ResEndDate = dpEnd.ToString();
myReservation.ResStartDate = dpStart.ToString();
CreateRes createReservation = new CreateRes();
createReservation.Show();
//I think the same problem lies here that is in the MainWindow.
myPerson = createReservation.myPerson;
this.Close();
}
}
And the last class follows:
public partial class CreateRes : Window
{
public Person myPerson
{
get;
set;
}
public CreateRes()
{
InitializeComponent();
myPerson = new Person();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
private void btnOk_Click(object sender, RoutedEventArgs e)
{
myPerson.FirstName = txtFName.Text;
myPerson.LastName = txtLName.Text;
myPerson.IdNumber = Convert.ToInt32(txtIdNumber.Text);
myPerson.PhoneNumber = Convert.ToInt32(txtPhoneNumber.Text);
myPerson.AddressCity = txtAddressCity.Text;
myPerson.AddressStreet = txtAddressStreet.Text;
myPerson.AddressProvince = txtAddressProvince.Text;
myPerson.AddressPostalCode = txtAddressPostalCode.Text;
this.Close();
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
Just make a overload constructor which takes parameters of the window in which you want to retrieve.
Example:
Suppose we want a user to login from our MainWindow( i.e Login Window ) and we want to pass an int ID / string Email to our second form to retrieve data of logging user.
Than We have to first overload our second wpf form constructor. You can either make default constructor to do this or make an overload constructor for this work.
SecondForm:
public secondForm()
{
//Your Default Constructor Logic
}
public secondForm(string email_ )
{
//Your Overload Constructor Logic
}
Now in MainWindow from where we are logging and passing our EMail
MainWindow:
public void btnLogin()
{
//On Success
SecondWindow sw = new SecondWindow(txtBoxEMail.Content);
sw.Show();
}
A pattern you can use for this sort of thing is to have each form be responsible for creating the instance on ok click and then provide the object via a property get.
public partial class SomeForm: Window
{
public SomeClass MyProperty { get; private set; }
private void btnOk_Click(object sender, RoutedEventArgs e)
{
this.MyProperty = new SomeClass();
//additional setter logic here
this.Close();
}
}
Then you would access it from a parent form like this (notice the use of ShowDialog() http://msdn.microsoft.com/en-us/library/system.windows.window.showdialog(v=vs.110).aspx for easy checking of whether ok was clicked or not).
protected void Create_Reservation_Click(object sender, RoutedEventArgs e)
{
SomeClass myObj;
SomeOtherClass myOtherObj;
SomeForm myForm = new SomeForm();
if(myForm.Show().Value)
{
myObj = myForm.MyProperty;
}
SomeOtherForm myOtherForm = new SomeOtherForm();
if(myOtherForm.ShowDialog().Value)
{
myOtherObj = myOtherForm.MyOtherProp;
}
//save myObj & myOtherObj or whatever you need to do with them
Use the "normal way", here is a short overview.
First create a Data Context:
public class DC_Reservation() : INotifyPropertyChanged {
protected Reservation _PersonReservation ;
public Reservation PersonReservation {
get { return _PersonReservation ; }
set {
_PersonReservation = value;
NotifyPropertyChanged("PersonReservation ");
}
}
protected Room _PersonRoom ;
public Room PersonRoom {
get { return _PersonRoom ; }
set {
_PersonRoom = value;
NotifyPropertyChanged("PersonRoom");
}
}
protected Person _myPerson ;
public Person myPerson {
get { return _myPerson ; }
set {
_myPerson = value;
NotifyPropertyChanged("myPerson ");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged( string PropertyName ) {
if ( PropertyChanged != null ) {
PropertyChanged( this, new PropertyChangedEventArgs( PropertyName ) );
}
}
}
In the MainWindows you can assign and use the dataContext :
public partial class MainWindow : Window {
DC_Reservation dataContext {
get { return DataContext as DC_Reservation; }
}
private string message;
public MainWindow() {
InitializeComponent();
DataContext = new DC_Reservation();
}
protected void Create_Reservation_Click(object sender, RoutedEventArgs e) {
dataContext.PersonReservation = new Reservation();//Create a reservation instance
dataContext.PersonRoom = new Room(); //Create an instance of a room
dataContext.myPerson = new Person();//Create an instance of a person
CreateResRoom createReservationRoom = new CreateResRoom();//Create a instance of the CreateReservation WPF Form
// I'm not sure whether the next line is required.
createReservationRoom.DataContext = DataContext;
createReservationRoom.Show();
}
}
You can assign the DataContext in the constructor, but I think the better way is to define the DataContext in the MainWindow, in the other windows you can use the DesignContext:
<Window.DataContext>
<local:DC_Reservation />
</Window.DataContext>
So you can use the same DataContext over all forms ...
With DataBindings you can bind the input to the field:
<TextBox Text="{Binding FirstName, Path=myPerson, Mode=TwoWay}" />
I found another answer that Zarathos posted Jan 16 '13 at 21:43
for a different question
Use a public static class and access it from anywhere.
public static class Globals
{
public static String s_Name = "Mike"; //Modifiable in Code
public const int32 VALUE = 10; // unmodifiable
}
Then you can use it anywhere, provided you are working on the same namespace
string name = Globals.s_Name;

Make a radio button input from a form public in C#?

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.

How do I pass variables to a buttons event method?

I need to be able to pass along two objects to the method being fired when I click a button. How do I do this?
So far I've been looking at creating a changed EventArgs:
public class CompArgs : System.EventArgs
{
private object metode;
private Type typen;
public CompArgs(object m, Type t)
{
this.metode = m;
this.typen = t;
}
public object Metode()
{
return metode;
}
public Type Typen()
{
return typen;
}
}
But how would I use it? Is it possible to somehow override the click-event of the button to use a custom eventhandler, which takes CompArgs as a parameter?
private void button1_Click(object sender, EventArgs e)
{
Assembly assembly = Assembly.LoadFile(#"c:\components.dll");
int counter = 0;
foreach (Type type in assembly.GetTypes())
{
if (type.IsClass == true)
{
Button btn = new Button();
btn.Location = new Point(174 + (counter * 100),10);
btn.Size = new Size(95, 23);
btn.Name = type.Name;
btn.Text = type.Name;
btn.UseVisualStyleBackColor = true;
this.Controls.Add(btn);
object obj = Activator.CreateInstance(type);
//I need to pass on obj and type to the btn_Click
btn.Click += new eventHandler(btn_Click);
counter++;
}
}
}
And the event-method where I need it:
private void btn_Click(object sender, CompArgs ca)
{
MessageBox.Show((string)ca.Typen().InvokeMember("getMyName",
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
ca.Metode(),
null));
}
Wow, you guys are making this entirely to difficult. No need for any custom classes or method overrides. In this example I just need to pass a tab index number. You can specify whatever you want, so long as your method is expecting that value type.
button.Click += (sender, EventArgs) => { buttonNext_Click(sender, EventArgs, item.NextTabIndex); };
void buttonNext_Click(object sender, EventArgs e, int index)
{
//your code
}
Cant you just set a property or member variable on the form that hosts the button and access these from the button click event?
EDIT: custom button class suggestion after feedback comment (not the same suggestion as above)
class MyButton : Button
{
private Type m_TYpe;
private object m_Object;
public object Object
{
get { return m_Object; }
set { m_Object = value; }
}
public Type TYpe
{
get { return m_TYpe; }
set { m_TYpe = value; }
}
}
Button1Click(object sender, EventArgs args)
{
MyButton mb = (sender as MyButton);
//then you can access Mb.Type
//and Mb.object
}
I'd create a new Button and override the OnClick method. Rather than passing down the EventArgs, pass a new derived class in with your additional members.
On the delegate receiving the event, cast the given EventArgs to the more derived class you're expecting to get, alternatively setup a new Event that will be triggered at the same time when the button is pressed and hook up to that instead to make things more implicit.
Example Code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ButtonEx b1 = new ButtonEx();
b1.OnCustomClickEvent += new ButtonEx.OnCustomClickEventHandler(b1_OnCustomClickEvent);
}
void b1_OnCustomClickEvent(object sender, ButtonEx.CustomEventArgs eventArgs)
{
string p1 = eventArgs.CustomProperty1;
string p2 = eventArgs.CustomProperty2;
}
}
public class ButtonEx : Button
{
public class CustomEventArgs : EventArgs
{
public String CustomProperty1;
public String CustomProperty2;
}
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
if(OnCustomClickEvent != null)
{
OnCustomClickEvent(this, new CustomEventArgs());
}
}
public event OnCustomClickEventHandler OnCustomClickEvent;
public delegate void OnCustomClickEventHandler(object sender , CustomEventArgs eventArgs);
}
You could use the Tag property of the button. You can add a string value to this property from the designer properties window and then pick it up within the handler as so:
private void MyButton_Click(object sender, EventArgs e)
{
string tagValue = ((Button) sender).Tag;
if(tag == "blah")
{
// Do something
}
}
Not sure if this exists in Winforms but it does in WPF: There is a "tag" object on all controls which you can attach any object to. You could save the object that you want to pass and then in the event handler read it back out of the sender object.
private void Button_Click(object sender, RoutedEventArgs e)
{
var note = (sender as FrameworkElement).Tag as Note;
//Do something with note here
}
You can't use your own custom event argument class for a predefined event handler signature. At least, the custom event argument type will never be utilised by any default calls to the handler (which will only ever be of type EventArgs in the case of a button); you could, potentially, call the handler yourself, passing your custom type, however, you would need to have logic in order to cast it back from an EventArgs into that which it had been cast from.
As a possible solution (depending on your situation), consider a composite type to encapsulate the items you require, as with your event argument type, but keep the required instance as an accessible variable which can be utilised from within the event handler, or, at least, by the method/s which the even handler invokes.
For example, define your type...
public class MyType
{
public object AccessibleItem { get; set; }
}
And, in your form class...
private MyType MyTypeInstance = new MyType();
private void Button_Click(object sender, EventArgs e)
{
//here we can set the item, if needs be...
MyTypeInstance.AccessibleItem = new Anything();
//or access the item to use as required...
DoSomeMagicWithMyObject(MyTypeInstance.AccessibleItem);
}
EDIT:
Okay, looking at your current code I can only offer you this for now (it doesn't add the items to the forms control container and it uses a variable iterator within Linq (which I think is either frowned upon or just down-right wrong (?), but hey...):
private void BuildButtonToObjectDictionary()
{
int counter = 0;
var assembly = Assembly.LoadFile(#"c:\components.dll");
var buttonToObjectDictionary = (
from type in assembly.GetTypes()
where type.IsClass && !type.IsAbstract
select new
{
Button = new Button
{
Name = type.Name,
Text = type.Name,
Size = new Size(95, 25),
Location = new Point(175 + (counter * 100), 10),
UseVisualStyleBackColor = true
},
Item = Activator.CreateInstance(type),
Index = counter++
});
}
Would need to see more code to give a better answer, but you could create an event that takes your CompArgs as a parameter and is fired when the buttonEvent is captured
If you open yourForm.Designer.cs file you will see all the code auto generated by VS. Here you can alter the method called when clicking on the button (or add a second method).
this.yourButton.Location = new System.Drawing.Point(211, 51);
this.yourButton.Name = "yourButton";
this.yourButton.Size = new System.Drawing.Size(75, 23);
this.yourButton.TabIndex = 0;
this.yourButton.Text = "yourButton";
this.yourButton.UseVisualStyleBackColor = true;
this.yourButton.Click += new System.EventHandler(this.yourMethodHere(object1, object2);
Hope this helps.

Categories