[Mono-osx] OT: DotNet question that has been bugging me today

Matt Emson memsom at interalpha.co.uk
Mon Aug 3 09:39:48 EDT 2009


This is neither a specific Mono nor OSX question, but more of a general 
question - but as there are lots of clever types here I guess someone 
might know.

I was writing a piece of generic code to dynamically copy a menu 
structure and reate a button based view (don't ask, management request) 
and that wa all pretty simple. I got everything working well. However, I 
got to the part when I was attempting to hook up the events and realised 
I have no idea if it is even possible to do this!! I was using VB.NET 
(legacy code), but have been banging my head on the table all morning. 
Does anyone know how you can replicate the following:

buttonX.Click += SomeOtherComponent.Click;

This does not compile!! I looked and looked and most articles assume you 
will have the method attached to the event, except this is a big bolt on 
to legacy code that I'm not going to be able to change without a lot of 
tedious regression testing, especially as I'm actually hoping that the 
management will change their minds. So I solved the issue with a 
complete hack (aka "Shim" class) that takes the Component (i.e., above 
Control) and looks for the protected "OnClick" method using reflection 
and provides an implementation that essentially wraps the Invoke() for 
that method. Yes, very WinForms specific, but I assume the same would be 
true of the following code:

    class SomeTestClass
    {
      public delegate void TestDelegate();
      public event TestDelegate TestEvent = null;

      public SomeTestClass()
      {
      }

      private void SecretTestEventInvoke()
      {
        if (TestEvent != null)
        {
          TestEvent();
        }
      }
    }

    class ConvolutedExample
    {
      void TestMethod1()
      {
        Console.WriteLine("Some code for option 1");
      }

      void TestMethod2()
      {
        Console.WriteLine("Some code for option 2");
      }

      SomeTestClass test1 = null;

      //Ignore the fact I could store boolean - this is not the issue, 
the issue is
      //"getting the event" when we do not know which method it is 
attached to.
      //This example is purposefully convoluted to make is simple to 
read the logic.
      public void Main(bool useOptionOne)
      {
        test1 = new SomeTestClass();

        //so, we don't have a direct way of knowing which one was 
set.... (we are ignoring the bool, this we assume is
        //happenening in IDE/thirdparty generated code and we do not 
have access or ability to change.)
        if (useOptionOne)
          test1.TestEvent += TestMethod1;
        else
          test1.TestEvent += TestMethod2;
      }

      //yes - this is not really a "good" idea, it is just an 
illustration. 
      public SomeTestClass InitTest2()
      {
        //here we want to use the same method... except we can't get "at it"
        SomeTestClass test2 = new SomeTestClass();

        //here is the issue:
        test2.TestEvent += test1.TestEvent; //<----- does not compile!!! 
How does one get a reference to the Delegate this contains???

        return test2;
      }
    }

My answer is a complete hack and I'm really unhappy with it. If the 
"OnClick" method didn't exist, it wouldn't have worked also. I'm hoping 
I'm just being really dense today, because this should be possible!

Any ideas? TIA,

M


More information about the Mono-osx mailing list