Как передать переменные методу событий кнопок?
Мне нужно иметь возможность передать два объекта методу, который запускается при нажатии кнопки. Как это сделать?
До сих пор я искал создание измененного 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;
}
}
Но как бы я его использовал? Возможно ли каким-либо образом переопределить событие click-кнопки кнопки, чтобы использовать настраиваемый обработчик событий, который принимает CompArgs в качестве параметра?
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++;
}
}
}
И метод события, в котором он мне нужен:
private void btn_Click(object sender, CompArgs ca)
{
MessageBox.Show((string)ca.Typen().InvokeMember("getMyName",
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
ca.Metode(),
null));
}
Ответы
Ответ 1
Не можете ли вы указать свойство или переменную-член в форме, на которой размещена кнопка, и получить к ней доступ из события нажатия кнопки?
РЕДАКТИРОВАТЬ: предложение класса пользовательской кнопки после комментария обратной связи (не такое же предложение, как указано выше)
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
}
Ответ 2
Ничего себе, вы, ребята, делаете это полностью трудным. Нет необходимости в каких-либо пользовательских классах или переопределениях методов. В этом примере мне просто нужно передать номер индекса табуляции. Вы можете указать, что хотите, до тех пор, пока ваш метод ожидает этот тип значения.
button.Click += (sender, EventArgs) => { buttonNext_Click(sender, EventArgs, item.NextTabIndex); };
void buttonNext_Click(object sender, EventArgs e, int index)
{
//your code
}
Ответ 3
Я бы создал новую кнопку и переопределил метод OnClick. Вместо того, чтобы передавать EventArgs, передайте новый производный класс вместе с вашими дополнительными членами.
В делегате, принимающем событие, нарисуйте данные EventArgs на более производный класс, который вы ожидаете получить, альтернативно настройте новое событие, которое будет запущено одновременно с нажатием кнопки и подключится к этому вместо чтобы сделать вещи более неявными.
Пример кода:
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);
}
Ответ 4
Не уверен, что это существует в Winforms, но это происходит в WPF: на всех элементах управления, к которым вы можете присоединить любой объект, есть объект "tag". Вы можете сохранить объект, который хотите передать, а затем в обработчике события его вернуть обратно из объекта отправителя.
private void Button_Click(object sender, RoutedEventArgs e)
{
var note = (sender as FrameworkElement).Tag as Note;
//Do something with note here
}
Ответ 5
Вы не можете использовать свой собственный класс аргументов событий для предопределенной подписи обработчика событий. По крайней мере, тип аргумента настраиваемого события никогда не будет использоваться никакими вызовами по умолчанию для обработчика (который будет только когда-либо иметь тип EventArgs
в случае кнопки); вы могли бы, потенциально, вызвать обработчик самостоятельно, передав свой собственный тип, однако вам понадобится логика, чтобы отбросить его с EventArgs
на то, из которого оно было выполнено.
В качестве возможного решения (в зависимости от вашей ситуации) рассмотрите составной тип для инкапсуляции требуемых элементов, например, с типом аргумента события, но сохраните требуемый экземпляр как доступную переменную, которая может быть использована из обработчика события, или, по крайней мере, методом /s, который вызывает четный обработчик.
Например, определите свой тип...
public class MyType
{
public object AccessibleItem { get; set; }
}
И, в вашем классе формы...
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:
Хорошо, глядя на ваш текущий код, я могу предложить вам это только сейчас (он не добавляет элементы в контейнер управления формами и использует переменный итератор в Linq (который, я думаю, либо нахмурился, либо просто опущен -правил неправильно (?), но эй...):
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++
});
}
Ответ 6
Вы можете использовать свойство Tag свойства кнопки. Вы можете добавить строковое значение к этому свойству из окна свойств конструктора, а затем выбрать его в обработчике так:
private void MyButton_Click(object sender, EventArgs e)
{
string tagValue = ((Button) sender).Tag;
if(tag == "blah")
{
// Do something
}
}
Ответ 7
Нужно будет увидеть больше кода, чтобы дать лучший ответ, но вы могли бы создать событие, которое принимает ваши CompArgs в качестве параметра и запускается при захвате buttonEvent
Ответ 8
Если вы откроете файл yourForm.Designer.cs, вы увидите весь код, автоматически созданный VS. Здесь вы можете изменить метод, вызванный при нажатии на кнопку (или добавление второго метода).
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);
Надеюсь, что это поможет.