Je dois pouvoir transmettre deux objets à la méthode en cours de lancement lorsque je clique sur un bouton. Comment puis-je faire cela?
Jusqu'à présent, je cherchais à créer un eventArgs modifié:
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;
}
}
Mais comment pourrais-je l'utiliser? Est-il possible en quelque sorte de remplacer l'événement click du bouton pour utiliser un gestionnaire d'événements personnalisé, qui prend CompArgs en paramètre?
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++;
}
}
}
Et la méthode d'événement où j'en ai besoin:
private void btn_Click(object sender, CompArgs ca)
{
MessageBox.Show((string)ca.Typen().InvokeMember("getMyName",
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
ca.Metode(),
null));
}
Ne pouvez-vous pas simplement définir une propriété ou une variable membre sur le formulaire qui héberge le bouton et y accéder à partir de l'événement click du bouton?
EDIT: suggestion de classe de bouton personnalisé après commentaire (pas la même suggestion que ci-dessus)
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
}
Wow, vous rendez cela vraiment difficile. Pas besoin de classes personnalisées ou de substitutions de méthodes. Dans cet exemple, je dois simplement passer un numéro d’index de tabulation. Vous pouvez spécifier ce que vous voulez, tant que votre méthode attend ce type de valeur.
button.Click += (sender, EventArgs) => { buttonNext_Click(sender, EventArgs, item.NextTabIndex); };
void buttonNext_Click(object sender, EventArgs e, int index)
{
//your code
}
Je créerais un nouveau bouton et substituerais la méthode OnClick. Plutôt que de transmettre les EventArgs, transmettez une nouvelle classe dérivée avec vos membres supplémentaires.
Sur le délégué recevant l'événement, transformez les EventArgs donnés en classes plus dérivées que vous espériez obtenir, ou configurez un nouvel événement qui sera déclenché en même temps lorsque le bouton est enfoncé. plus implicite.
Exemple de 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);
}
Vous pouvez utiliser la propriété Tag du bouton. Vous pouvez ajouter une valeur de chaîne à cette propriété à partir de la fenêtre de propriétés du concepteur, puis la sélectionner dans le gestionnaire comme suit:
private void MyButton_Click(object sender, EventArgs e)
{
string tagValue = ((Button) sender).Tag;
if(tag == "blah")
{
// Do something
}
}
Pas sûr que cela existe dans Winforms mais dans WPF: Il existe un objet "tag" sur tous les contrôles auquel vous pouvez attacher un objet. Vous pouvez enregistrer l'objet que vous voulez transmettre et le relire ensuite dans l'objet de l'expéditeur.
private void Button_Click(object sender, RoutedEventArgs e)
{
var note = (sender as FrameworkElement).Tag as Note;
//Do something with note here
}
Vous ne pouvez pas utiliser votre propre classe d'argument d'événement personnalisé pour une signature de gestionnaire d'événement prédéfinie. Au moins, le type d'argument d'événement personnalisé ne sera jamais utilisé par aucun appel par défaut au gestionnaire (qui ne sera jamais que du type EventArgs
dans le cas d'un bouton); vous pouvez éventuellement appeler le gestionnaire vous-même en transmettant votre type personnalisé. Toutefois, vous devez disposer d'une logique pour pouvoir le retransformer d'une EventArgs
dans celui dans lequel il a été lancé.
En tant que solution possible (selon votre situation), envisagez un type composite pour encapsuler les éléments dont vous avez besoin, comme avec votre type d'argument d'événement, tout en conservant l'instance requise comme variable accessible pouvant être utilisée à partir du gestionnaire d'événements. au moins, par la/les méthode (s) invoquée (s) par le gestionnaire pair.
Par exemple, définissez votre type ...
public class MyType
{
public object AccessibleItem { get; set; }
}
Et, dans votre classe de formulaire ...
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);
}
MODIFIER:
En regardant votre code actuel, je ne peux que vous proposer ceci pour le moment (il n'ajoute pas les éléments au conteneur de contrôle des formulaires et utilise un itérateur variable dans Linq (ce qui, à mon avis, est mal vu ou tout simplement faux. (?), Mais salut...):
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++
});
}
Aurait besoin de voir plus de code pour donner une meilleure réponse, mais vous pouvez créer un événement qui prend vos CompArgs en tant que paramètre et qui est déclenché lorsque le buttonEvent est capturé
Si vous ouvrez le fichier yourForm.Designer.cs, vous verrez tout le code généré automatiquement par VS. Ici, vous pouvez modifier la méthode appelée en cliquant sur le bouton (ou ajouter une deuxième méthode).
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);
J'espère que cela t'aides.