问题
I have a C# main form that opens up C# sub forms in separate tabs. Each tab is simply an instance of the same sub form so the tab code is like:
SubForm sf = new SubForm();
TabPage tp = new TabPage();
tp.Controls.Add(sf);
tabControl.TabPages.Add(tp);
There can be n tabs and subforms. Then each new subform instance has a delegate to handle external event updates, like so:
public partial class SubForm : Form
{
... form setup ...
internal void DoStuff(value v)
{
if (InvokeRequired)
{
// Generic Action delegate
Invoke(new Action<string, string>(DoStuff), value);
return;
}
myLabel.Text = value;
Show();
}
}
Click the subscribe button and there's a Geode registration to specific keys in the subform, and the delegate is passed as an event handler:
private void button_Click(object sender, EventArgs e)
{
new Geode().RegisterMyListener(cache, key, DoStuff);
}
When the Geode key value is updated then the update is handled.
This is working fine for the 1st subform. Then with a 2nd or 3rd subform all the Geode subscriptions to each subform's keys are updating, but all the updates are being handled only by the most recently instantiated subform's delegate. I had not expected that to happen because doesn't each new subform instance have its own stack with a new delegate?
UPDATE: Once a 2nd key is registered with Geode RegisterMyListener
like this:
region.GetSubscriptionService().RegisterKeys(s);
region.AttributesMutator.SetCacheListener(new Listener<string, string>(DoStuff));
then every event update references the latest DoStuff
delegate and never a previous one. So is a Geode listener a static
register? I am looking to be able to subscribe to separate keys with many instances of the same Listener
. Is that possible? Or am I going to need multiple listeners for multiple subforms?
回答1:
You can do it with extension method like this:
public static class Extensions
{
public static void InvokeAction(this Control control, Action action)
{
if (control.InvokeRequired)
{
control.Invoke(new MethodInvoker(() => { action(); }));
}
else
{
action();
}
}
}
Usage:
public partial class SubForm : Form
{
public void SetExampleText(string text)
{
this.InvokeAction(() => { this.ExampleTextBox.Text = text; })
}
}
来源:https://stackoverflow.com/questions/48622814/c-sharp-winform-delegates-for-n-subforms