In C#, how do I code 'this = that'?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Charles Jenkins

    In C#, how do I code 'this = that'?

    I want to make a MenuItem that I can 'click' programmaticall y. I
    started by coding this:

    class ClickableMenuIt em : MenuItem {

    public void DoClick( EventArgs e ) {
    OnClick( e );
    }

    ClickableMenuIt em( MenuItem mi ) {
    // What do I do here?!?
    // this = mi; <--- does not work
    }
    }

    As you can see, I have no idea of how to tell ClickableMenuIt em to take
    all of its fields and events from MenuItem upon construction.

    How would you do this?

  • Marc Gravell

    #2
    Re: In C#, how do I code 'this = that'?

    In inheritance, the sub-class *is intrinsically composed of* the base
    class, so you can't pass another one into the ctor for it to absorb.
    You could theoretically pass one in as a template to copy, but I don't
    think this is what you are trying to achieve.
    However, you also shouldn't need to do any of this...

    Assuming you make ctors available on ClickableMenuIt em to mimic the
    ctors of MenuItem, then it should be enough to simple create and add
    ClickableMenuIt em instances to your menus, instead of MenuItem
    instances. The downside is that this might confuse the IDE a bit,
    maybe.

    Marc

    Comment

    • Mathieu Cartoixa

      #3
      Re: In C#, how do I code 'this = that'?

      Charles Jenkins a écrit :
      I want to make a MenuItem that I can 'click' programmaticall y. I started
      by coding this:
      >
      class ClickableMenuIt em : MenuItem {
      >
      public void DoClick( EventArgs e ) {
      OnClick( e );
      }
      >
      ClickableMenuIt em( MenuItem mi ) {
      // What do I do here?!?
      // this = mi; <--- does not work
      }
      }
      >
      As you can see, I have no idea of how to tell ClickableMenuIt em to take
      all of its fields and events from MenuItem upon construction.
      >
      How would you do this?
      >
      Hi,

      Have you checked the method MenuItem.Perfor mClick in MSDN ?...

      As for your solution, I think you are a bit confused because you want
      both inheritance and composition : you will have to choose. If you
      inherit from MenuItem, then why not create a ClickableMenuIt em instance
      whenever you need one, instead of creating a MenuItem instance that will
      only be used to initialize a new ClickableMenuIt em instance ?...

      OK, I guess that is because you used the designer to create your menu,
      and you could only create MenuItem instances this way... Then there
      would be three workarounds :
      * isolate your ClickableMenuIt em in a library and add it to the
      designer controls. Use inheritance. The constructor would have no
      parameters, and you could use it exactly like a MenuItem.
      * create your ClickableMenuIt em elements "by hand" in your form
      constructor, after the call to InitializeCompo nents(). Use inheritance.
      You would not want any parameter in your constructor either.
      * let the designer create your MenuItem. Then create your
      ClickableMenuIt em elements "by hand" in your form constructor, after the
      call to InitializeCompo nents(). Use composition (which in this case
      seems to be a rather long and fastidious if you do it properly...).

      Hope this helps.

      Mathieu

      Comment

      • Charles Jenkins

        #4
        Re: In C#, how do I code 'this = that'?

        On 2006-08-21 10:16:34 -0400, "Marc Gravell" <marc.gravell@g mail.comsaid:
        Assuming you make ctors available on ClickableMenuIt em to mimic the
        ctors of MenuItem, then it should be enough to simple create and add
        ClickableMenuIt em instances to your menus, instead of MenuItem
        instances. The downside is that this might confuse the IDE a bit,
        maybe.
        >
        Marc
        Your advice is perfect, but I have had severe problems lately in that
        any custom conrol I create works just fine for a while, but sooner or
        later, they always confuse the IDE. The VS 2005 Designer gets in a
        state where it will no longer display the custom control (or any form
        which contains it).

        Therefore, I am trying to find a solution that allow me to use only
        standard controls on my form, with no visual inheritance, and then add
        the behaviors I actually need at runtime. I was hoping to be able to do
        something like this:

        // Convert the control the designer understands to the one I actually need
        ClickableMenuIt em usefulMenuItem = new ClickableMenuIt em(
        sadlyLimitedMen uItem );
        usefulMenuItem. DoClick();

        But, you are absolutely right: If the Visual Studio 2005 designer
        didn't suck, using inherited controls in the IDE would be the correct
        solution

        Comment

        • Greg Young

          #5
          Re: In C#, how do I code 'this = that'?

          Aside from Mathieu's great point on "PerformCli ck" ...

          It seems that what you are trying to do is a decorator pattern (perhaps a
          look at the pattern will clear thing sup a bit?)

          Cheers,

          Greg
          "Charles Jenkins" <not.my.address @not.here.comwr ote in message
          news:2006082110 040716807-notmyaddress@no therecom...
          >I want to make a MenuItem that I can 'click' programmaticall y. I started by
          >coding this:
          >
          class ClickableMenuIt em : MenuItem {
          >
          public void DoClick( EventArgs e ) {
          OnClick( e );
          }
          >
          ClickableMenuIt em( MenuItem mi ) {
          // What do I do here?!?
          // this = mi; <--- does not work
          }
          }
          >
          As you can see, I have no idea of how to tell ClickableMenuIt em to take
          all of its fields and events from MenuItem upon construction.
          >
          How would you do this?
          >

          Comment

          • Charles Jenkins

            #6
            Re: In C#, how do I code 'this = that'?

            On 2006-08-21 10:38:52 -0400, Mathieu Cartoixa
            <mathieu.cartoi xa@_NO_hotmail_ SPAM_.comsaid:

            Thanks for trying to help me!
            Have you checked the method MenuItem.Perfor mClick in MSDN ?...
            I am using the .NET Compact Framework, which seems to be designed for
            frustration, becaue the method you NEED is never available. For
            instance, MenuItem.Perfor mClick() does not exist in the Compact
            Framework.

            As for your solution, I think you are a bit confused because you want
            both inheritance and composition : you will have to choose. If you
            inherit from MenuItem, then why not create a ClickableMenuIt em instance
            whenever you need one, instead of creating a MenuItem instance that
            will only be used to initialize a new ClickableMenuIt em instance ?...
            >
            OK, I guess that is because you used the designer to create your menu,
            and you could only create MenuItem instances this way... Then there
            would be three workarounds :
            Great guesses! You are really sharp!

            Because the VS 2005 designer is not reliable for custom controls, I am
            trying to put plain old controls (with no visual inheritance) onto my
            forms, then add the behaviors I need at runtime. I need
            ClickableMenuIt em to inherit from MenuItem so that it can call
            OnClick(); but I need each new ClickableMenuIt em to get its state from
            the MenuItem that is actually available. I want to be able to do
            something like this:

            // Use what we have to create what we actually need
            ClickableMenuIt em cmi = new ClickableMenuIt em( menuItem );
            cmi.DoClick();
            * isolate your ClickableMenuIt em in a library and add it to the
            designer controls. Use inheritance. The constructor would have no
            parameters, and you could use it exactly like a MenuItem.
            I think this would require the kind of inheritance that would lead me
            to have problems with the designer. In order to add ClickableMenuIt ems
            using the designer, I would have to create a ClickableContex tMenu,
            right?
            * create your ClickableMenuIt em elements "by hand" in your form
            constructor, after the call to InitializeCompo nents(). Use inheritance.
            You would not want any parameter in your constructor either.
            * let the designer create your MenuItem. Then create your
            ClickableMenuIt em elements "by hand" in your form constructor, after
            the call to InitializeCompo nents(). Use composition (which in this case
            seems to be a rather long and fastidious if you do it properly...).
            These workarounds still require me to make the ClickableMenuIt em to get
            its state (fields and event handlers) from the MenuItem I want to
            impersonate. That leads me back to this question. Given that I cannot
            say "this = that," how do I copy all the MenuItem's fields and events
            from the MenuItem I have into the ClickableMenuIt em that I want?

            Oddly enough, I really *did* attempt to combine inheritance and
            composition, just like you guessed, in the hope that an inherited
            control could gain access to the protected methods of the member
            control's instance---

            class ClickableMenuIt em : MenuItem {

            private MenuItem m_mi;

            public ClickableMenuIt em( MenuItem mi ) {
            m_mi = mi;
            }

            public void DoClick( EventArgs e ) {
            m_mi.OnClick( e );
            }
            }

            Of course, that does not work. I can call OnClick() in my own instance
            (where it would do no good) but not in m_mi (which has the handlers I
            want to fire). That approach would have been wrong and very wasteful,
            but if it had worked, I could have lived with it.

            Have a great day, and thanks!

            Comment

            • Charles Jenkins

              #7
              Re: In C#, how do I code 'this = that'?

              On 2006-08-21 12:13:55 -0400, "Greg Young"
              <druckdruckREMO VEgoose@hotmail .comsaid:
              Aside from Mathieu's great point on "PerformCli ck" ...
              >
              It seems that what you are trying to do is a decorator pattern (perhaps
              a look at the pattern will clear thing sup a bit?)
              I have a book on C# Design Patterns, so I will do just as you say and
              read up on the Decorator pattern.

              Thanks!

              Comment

              • Andreas Mueller

                #8
                Re: In C#, how do I code 'this = that'?

                Charles Jenkins wrote:
                On 2006-08-21 10:16:34 -0400, "Marc Gravell" <marc.gravell@g mail.comsaid:
                >
                >Assuming you make ctors available on ClickableMenuIt em to mimic the
                >ctors of MenuItem, then it should be enough to simple create and add
                >ClickableMenuI tem instances to your menus, instead of MenuItem
                >instances. The downside is that this might confuse the IDE a bit,
                >maybe.
                >>
                >Marc
                >
                >
                Your advice is perfect, but I have had severe problems lately in that
                any custom conrol I create works just fine for a while, but sooner or
                later, they always confuse the IDE. The VS 2005 Designer gets in a state
                where it will no longer display the custom control (or any form which
                contains it).
                Are your custom controls and the containing controls in the same
                project? The VS2003 designer had problems with that, so the VS2005
                designer might have them, too. It typically happened when I had a user
                control and one that contains it open inside the designer at the same time.
                The solution was to factor the user controls into another library.

                Also, whenever you encounter such an behavior, don't save anything,
                close all open windows then and close VS. Then delete the bin and obj
                folder. Reopen VS and recompile the solution. Should work fine again.

                Its not a perfect solution, but I can live with this workaround since
                VS2002 :-(


                HTH,
                Andy

                Comment

                • Bruce Wood

                  #9
                  Re: In C#, how do I code 'this = that'?

                  Your advice is perfect, but I have had severe problems lately in that
                  any custom conrol I create works just fine for a while, but sooner or
                  later, they always confuse the IDE. The VS 2005 Designer gets in a
                  state where it will no longer display the custom control (or any form
                  which contains it).
                  I'm still using VS2003, but when I experience problems like this I find
                  that they are usually related to compilation of dependant assemblies.
                  Are your custom controls in a DLL that is then used by the project
                  experiencing the difficulties?

                  Come to think of it, I've even seen this behaviour when the custom
                  controls are defined in the same project. My solution: close all
                  designer windows without saving anything, close the solution, recompile
                  all solutions from the "bottom up": library DLLs, then control DLLs,
                  then data layer, then business layer, then UI. That seems to sort it
                  out.

                  Of course, VS 2005 may have different problems....

                  Comment

                  • Charles Jenkins

                    #10
                    Re: In C#, how do I code 'this = that'?

                    On 2006-08-21 12:51:12 -0400, "Bruce Wood" <brucewood@cana da.comsaid:
                    I'm still using VS2003, but when I experience problems like this I find
                    that they are usually related to compilation of dependant assemblies.
                    Are your custom controls in a DLL that is then used by the project
                    experiencing the difficulties?
                    >
                    Come to think of it, I've even seen this behaviour when the custom
                    controls are defined in the same project. My solution: close all
                    designer windows without saving anything, close the solution, recompile
                    all solutions from the "bottom up": library DLLs, then control DLLs,
                    then data layer, then business layer, then UI. That seems to sort it
                    out.
                    >
                    Of course, VS 2005 may have different problems....
                    I have tried the shutdown/delete bin and obj/restart routine, and it
                    does not help; but your advice to manually rebuild each assembly in
                    turn is interesting. The next time I cannot avoid doing a custom
                    control, if the problem recurs, I will try that procedure.

                    Thank you, Bruce and Andreas!

                    Comment

                    • Charles Jenkins

                      #11
                      Re: In C#, how do I code 'this = that'?

                      On 2006-08-21 12:49:18 -0400, Andreas Mueller <me@privacy.net said:
                      Are your custom controls and the containing controls in the same
                      project? The VS2003 designer had problems with that, so the VS2005
                      designer might have them, too. It typically happened when I had a user
                      control and one that contains it open inside the designer at the same
                      time.
                      The solution was to factor the user controls into another library.
                      >
                      Also, whenever you encounter such an behavior, don't save anything,
                      close all open windows then and close VS. Then delete the bin and obj
                      folder. Reopen VS and recompile the solution. Should work fine again.
                      >
                      Its not a perfect solution, but I can live with this workaround since
                      VS2002 :-(
                      They are in a separate project within the same solution. I made a
                      mistake when I said the designer would not display the control or forms
                      that contain it. Typically, the control will display just fine in the
                      designer when I look at it and it will comple and run without a
                      problem. It is when I put the control on a form that the form becomes
                      unusable in the designer.

                      Thanks!

                      Comment

                      • Mathieu Cartoixa

                        #12
                        Re: In C#, how do I code 'this = that'?

                        Charles Jenkins a écrit :
                        On 2006-08-21 10:38:52 -0400, Mathieu Cartoixa
                        <mathieu.cartoi xa@_NO_hotmail_ SPAM_.comsaid:
                        >
                        > Have you checked the method MenuItem.Perfor mClick in MSDN ?...
                        >
                        I am using the .NET Compact Framework, which seems to be designed for
                        frustration, becaue the method you NEED is never available. For
                        instance, MenuItem.Perfor mClick() does not exist in the Compact Framework.
                        I must admit I never used the Compact Framework. PerformClick seems to
                        be available for buttons, but not for menu items in this world :-(
                        <snip>
                        >
                        Because the VS 2005 designer is not reliable for custom controls, I am
                        trying to put plain old controls (with no visual inheritance) onto my
                        forms, then add the behaviors I need at runtime. I need
                        ClickableMenuIt em to inherit from MenuItem so that it can call
                        OnClick(); but I need each new ClickableMenuIt em to get its state from
                        the MenuItem that is actually available. I want to be able to do
                        something like this:
                        >
                        // Use what we have to create what we actually need
                        ClickableMenuIt em cmi = new ClickableMenuIt em( menuItem );
                        cmi.DoClick();
                        >
                        Well, except with Delphi, I have always been disappointed with
                        designers. The code they ususally produce is such a mess that they end
                        up being unable to deal with it after a while...

                        > * isolate your ClickableMenuIt em in a library and add it to the
                        >designer controls. Use inheritance. The constructor would have no
                        >parameters, and you could use it exactly like a MenuItem.
                        >
                        I think this would require the kind of inheritance that would lead me to
                        have problems with the designer. In order to add ClickableMenuIt ems
                        using the designer, I would have to create a ClickableContex tMenu, right?
                        I do not think so, as with inheritance a ClickableMenuIt em would be a
                        MenuItem. That reminds me of a hack I have used with VS2003 that should
                        work with VS2005 : add a MenuItem to your menu vie the designer, save
                        your files, close the designer, and replace MenuItem with
                        ClickableMenuIt em directly in the source code for your instance (ther
                        should be only two occurrences : one in the variable declaration, one in
                        the method InitializeCompo nents). Reopen the designer : you are done !
                        >
                        > * create your ClickableMenuIt em elements "by hand" in your form
                        >constructor, after the call to InitializeCompo nents(). Use
                        >inheritance. You would not want any parameter in your constructor either.
                        > * let the designer create your MenuItem. Then create your
                        >ClickableMenuI tem elements "by hand" in your form constructor, after
                        >the call to InitializeCompo nents(). Use composition (which in this
                        >case seems to be a rather long and fastidious if you do it properly...).
                        >
                        These workarounds still require me to make the ClickableMenuIt em to get
                        its state (fields and event handlers) from the MenuItem I want to
                        impersonate. That leads me back to this question. Given that I cannot
                        say "this = that," how do I copy all the MenuItem's fields and events
                        from the MenuItem I have into the ClickableMenuIt em that I want?
                        The first method uses inheritance : you are just not using the designer
                        for your specific components.
                        >
                        Oddly enough, I really *did* attempt to combine inheritance and
                        composition, just like you guessed, in the hope that an inherited
                        control could gain access to the protected methods of the member
                        control's instance---
                        >
                        class ClickableMenuIt em : MenuItem {
                        >
                        private MenuItem m_mi;
                        >
                        public ClickableMenuIt em( MenuItem mi ) {
                        m_mi = mi;
                        }
                        >
                        public void DoClick( EventArgs e ) {
                        m_mi.OnClick( e );
                        }
                        }
                        I have been there before : no matter what you are trying to achieve,
                        inheritance cannot live with composition (wit the same class involved,
                        of course ;-). It is always wrong.
                        But here is your real point : how to simulate the click ? Be careful
                        that OnClick just triggers the handlers registered to the Click event,
                        it does not perform any MenuItem specific action associated with the
                        click... The best solution if you want to call OnClick anyway is to use
                        inheritance and just :

                        public void PerformClick() {
                        this.OnClick(ne w EventArgs());
                        }

                        What if OnClick is not enough ?... I would try to use a reflector to
                        look deep into the MenuItem class (you can find one there :
                        http://www.aisto.com/roeder/dotnet/), and look for a private method that
                        would look like a PerformClick. Then I would call it using reflection,
                        which is a secret way to bypass the laws of method accessibility
                        (beuaark)...


                        Last thougt : I think that if you really had separated UI code from the
                        rest, you would not have felt this need to call a method that does not
                        exist... Let me explain that : what I think you did is something that is
                        very usual thanks to designers, I mean add a handler to your MenuItem,
                        and perform your actual actions in there

                        public void MyForm_myMenuIt em_Click(object sender, EventArgs e) {
                        // related actions...
                        }

                        So now you will want to programmaticall y click the myMenuItem to
                        perform the actions... Try instead to separate the code related to your
                        actions in another layer (most likely in another class)

                        public void RelatedActions( )
                        {
                        // some code here
                        }

                        and just replace the preceding with :

                        public void MyForm_myMenuIt em_Click(object sender, EventArgs e) {
                        RelatedActions( );
                        }

                        Now, can you not try to call RelatedActions directly instead of trying
                        to click the menu ?
                        >
                        Of course, that does not work. I can call OnClick() in my own instance
                        (where it would do no good) but not in m_mi (which has the handlers I
                        want to fire). That approach would have been wrong and very wasteful,
                        but if it had worked, I could have lived with it.
                        >
                        Have a great day, and thanks!
                        >

                        Comment

                        • Simon Tamman

                          #13
                          Re: In C#, how do I code 'this = that'?

                          Patterns are fun, but watch out for the observer. That one can be dangerous.
                          :)

                          I find that I can "re-align" my designer if I re-inherit from a standard
                          windows component, rebuild, view in designer, close windows, then switch
                          back the inheritance and rebuild.
                          Failing that, I reset the toolbox, remove the reference, build (watch it
                          whinge about the missing reference) then re-add the assembly into the
                          toolbox and then it works.
                          Failing ALL of that, I create the real thing with windows control, detach
                          the windows control at runtime and use reflection to copy all the designer
                          settings and inner controls across to my inherited version.
                          You can't be bothered with that you could start up a brand new .sln and
                          possibly even .csproj and copy the files back into the new projects and
                          solutions (but the speed of that depends on how much stuff you have).
                          Just to double check, you are aware that all designer components must have
                          default parameterless, constructors, right?

                          God the designer can suck sometimes..... but it can work (e.g. it's not
                          completely broken), you just have to be persistent with it.

                          I concur that the .NET Compact Framework sucks in comparison, but apparently
                          older devs tell me it's better than what they previously had (so WTF was
                          that like????).
                          My favourite is the great exceptions you get:

                          System.Exceptio n
                          An exception occured

                          NO STACKTRACE. Arggghhhh!

                          Anyway, good luck.

                          Simon

                          "Charles Jenkins" <not.my.address @not.here.comwr ote in message
                          news:2006082112 423043658-notmyaddress@no therecom...
                          On 2006-08-21 12:13:55 -0400, "Greg Young"
                          <druckdruckREMO VEgoose@hotmail .comsaid:
                          >
                          Aside from Mathieu's great point on "PerformCli ck" ...

                          It seems that what you are trying to do is a decorator pattern (perhaps
                          a look at the pattern will clear thing sup a bit?)
                          >
                          I have a book on C# Design Patterns, so I will do just as you say and
                          read up on the Decorator pattern.
                          >
                          Thanks!
                          >

                          Comment

                          • Charles Jenkins

                            #14
                            Re: In C#, how do I code 'this = that'?

                            Hee hee! Thanks for the advice. Maybe I oughtta seriously think about
                            changing careers

                            On 2006-08-22 16:31:11 -0400, "Simon Tamman"
                            <i_am_GETRIDOFT HISJUNKanti_eve rything@NOSPAMh otmail.comsaid:
                            Patterns are fun, but watch out for the observer. That one can be dangerous.
                            :)
                            >
                            I find that I can "re-align" my designer if I re-inherit from a standard
                            windows component, rebuild, view in designer, close windows, then switch
                            back the inheritance and rebuild.
                            Failing that, I reset the toolbox, remove the reference, build (watch it
                            whinge about the missing reference) then re-add the assembly into the
                            toolbox and then it works.
                            Failing ALL of that, I create the real thing with windows control, detach
                            the windows control at runtime and use reflection to copy all the designer
                            settings and inner controls across to my inherited version.
                            You can't be bothered with that you could start up a brand new .sln and
                            possibly even .csproj and copy the files back into the new projects and
                            solutions (but the speed of that depends on how much stuff you have).
                            Just to double check, you are aware that all designer components must have
                            default parameterless, constructors, right?
                            >
                            God the designer can suck sometimes..... but it can work (e.g. it's not
                            completely broken), you just have to be persistent with it.
                            >
                            I concur that the .NET Compact Framework sucks in comparison, but apparently
                            older devs tell me it's better than what they previously had (so WTF was
                            that like????).
                            My favourite is the great exceptions you get:
                            >
                            System.Exceptio n
                            An exception occured
                            >
                            NO STACKTRACE. Arggghhhh!
                            >
                            Anyway, good luck.
                            >
                            Simon
                            >
                            "Charles Jenkins" <not.my.address @not.here.comwr ote in message
                            news:2006082112 423043658-notmyaddress@no therecom...
                            >On 2006-08-21 12:13:55 -0400, "Greg Young"
                            ><druckdruckREM OVEgoose@hotmai l.comsaid:
                            >>
                            >>Aside from Mathieu's great point on "PerformCli ck" ...
                            >>>
                            >>It seems that what you are trying to do is a decorator pattern (perhaps
                            >>a look at the pattern will clear thing sup a bit?)
                            >>
                            >I have a book on C# Design Patterns, so I will do just as you say and
                            >read up on the Decorator pattern.
                            >>
                            >Thanks!

                            Comment

                            • Charles Jenkins

                              #15
                              Re: In C#, how do I code 'this = that'?

                              You put a lot of time and thought into that, Matheiu, and I really
                              appreciate it. Thanks for helping me.

                              I will have to print out your reply and go over it very carefully.
                              Intuitively, I think your clues about better separating my actions from
                              user interface stuff are great points that may really help me as I
                              solve this problem and others in the future! :-D

                              Comment

                              Working...