{"id":1401,"date":"2022-09-29T18:56:21","date_gmt":"2022-09-30T00:56:21","guid":{"rendered":"https:\/\/www.great-white-software.com\/blog\/?p=1401"},"modified":"2022-09-29T18:56:21","modified_gmt":"2022-09-30T00:56:21","slug":"adding-menubar-controls-in-c","status":"publish","type":"post","link":"https:\/\/www.great-white-software.com\/blog\/2022\/09\/29\/adding-menubar-controls-in-c\/","title":{"rendered":"Adding menubar &#038; controls in C#"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">For all of you following along <strong>YEAH its about damned time !<\/strong> \ud83d\ude42<br>I agree<br><br>I&#8217;ve been proceeding slowly to make it so you can follow and not try to cram 10000 items in one post (we ARE trying to keep it manageable)<br><br>First Lets remove the last bits of &#8220;cruft&#8221; left in our getting starting project<br>Since we&#8217;re not actually using a normal macOS document application we can delete the <em>ViewController.cs<\/em> and <em>ViewController.designer.cs<\/em><br>Simply right click on <em>ViewController.cs <\/em>and select delete.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"502\" height=\"763\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.20.00-PM.png?resize=502%2C763&#038;ssl=1\" alt=\"\" class=\"wp-image-1402\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.20.00-PM.png?w=502&amp;ssl=1 502w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.20.00-PM.png?resize=197%2C300&amp;ssl=1 197w\" sizes=\"auto, (max-width: 502px) 100vw, 502px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ll get a dialog asking if you want to delete the view controller and its &#8220;code behind children&#8221; <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"98\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.20.13-PM.png?resize=525%2C98&#038;ssl=1\" alt=\"\" class=\"wp-image-1403\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.20.13-PM.png?resize=1024%2C192&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.20.13-PM.png?resize=300%2C56&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.20.13-PM.png?resize=768%2C144&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.20.13-PM.png?w=1144&amp;ssl=1 1144w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Select <em>Delete<\/em> and both will be removed. Your should still be able to run your application.<br><br>Now on to the fun stuff !<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First lets add a menu bar so we have a normal Quit menu Item in it \ud83d\ude1b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start by adding a new class (almost everything in our C# world is an actual class)<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"400\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.30.43-PM-1.png?resize=525%2C400&#038;ssl=1\" alt=\"\" class=\"wp-image-1405\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.30.43-PM-1.png?w=841&amp;ssl=1 841w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.30.43-PM-1.png?resize=300%2C228&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.30.43-PM-1.png?resize=768%2C584&amp;ssl=1 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">We end up with an empty class that we need to edit to set up properly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;re using an actual macOS NSMenu here &#8211; so we need to add the AppKit using clause so the IDE &amp; compiler know about this in our class. And we&#8217;ll make our AppMenu class a subclass of NSMenu<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"284\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.34.45-PM-1.png?resize=525%2C284&#038;ssl=1\" alt=\"\" class=\"wp-image-1407\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.34.45-PM-1.png?w=740&amp;ssl=1 740w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.34.45-PM-1.png?resize=300%2C163&amp;ssl=1 300w\" sizes=\"auto, (max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"> We&#8217;ll want to add &amp; retain references to certain menu items &#8211;  note this doesnt mean you cant handle dynamic menus. Just that there are some, like the Quit menu item, that we dont need to deal with dynamically. So we can add a property to our class to hold this reference when we create it<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    public class AppMenu : NSMenu\n    {\n        public static MenuItem QuitMenuItem;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And we&#8217;ll want to alter the Constructor (the method named the same as the class) so it takes one parameter &#8211; the menus TITLE<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class AppMenu : NSMenu\n{\n        public static MenuItem QuitMenuItem;\n\n        public AppMenu(string title) : base(title)\n        { }\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The AppMenu method is new so requires some explanation. The first portion<code> public AppMenu(string title)<\/code> is just like any other method you&#8217;ve ever seen. It has a scope <em><strong>public<\/strong><\/em>, a name <em><strong>AppMenu<\/strong><\/em>, and a list of parameters <em><strong>string title<\/strong><\/em>. But then there is<em> <\/em><strong><em>: base(title)<\/em> <\/strong>which in C# is shorthand for &#8220;call the super class constructor method that takes a string parameter&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So just by declaring the method this way you have created the constructor and call the super class constructor. But so far it doesnt do anything &#8211; the empty {} is the give away.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When an app start we need to create the &#8220;Application Menu&#8221; and add whatever items to it we want. On macOS the OS may add some of its own.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So we&#8217;ll create that menu and make it have a Quit item in it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public AppMenu(string title) : base(title)\n{\n  \/\/ Application top level Menu\n  var appMenu = new NSMenuItem(); \/\/ create the top item for Application\n  appMenu.Submenu = new NSMenu(); \/\/ add a sub menu\n\n  QuitMenuItem = new MenuItem(\"Quit\", \"q\"); \/\/ create the QUIT item\n\n  \/\/ create and set the ARRAY of items to a NEW ARRAY containing\n  \/\/ our newly created QuitMenuItem\n  appMenu.Submenu.Items = new&#91;]\n  {\n    QuitMenuItem\n  };\n\n  \/\/ THIS is like ME or SELF\n  \/\/ here this means the app menu itself\n  this.Items = new&#91;] { appMenu };\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will create the menu &#8211; but doesnt &#8220;attach&#8221; it to our application yet. So if you run right now you wont see this code get run. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can test this by setting a breakpoint in the code. There are several ways to achieve this. By default pressing CMD+\\ will toggle a break point on the line containing the insertion point. Or you can click in the break point gutter <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"329\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.56.28-PM.png?resize=525%2C329&#038;ssl=1\" alt=\"\" class=\"wp-image-1408\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.56.28-PM.png?w=918&amp;ssl=1 918w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.56.28-PM.png?resize=300%2C188&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-4.56.28-PM.png?resize=768%2C482&amp;ssl=1 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">When you run you will see that break point is NEVER reached.<br>So lets fix that.<br><br>Open up the <em>AppDelegate.cs<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When an applications starts up, just like in Xojo, you will see the constructor get called, followed by the app &#8220;Opening&#8221;. In this case we&#8217;re going to set up the menu, and &#8220;menu handlers&#8221; in the Opening event (its not really an event in this framework but thats what it would be in Xojo)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So &#8211; how to know what the method we need to implement might be named ?<br>We could guess. That might take a long time. <br>I could tell you but I might not be around all the time \ud83d\ude42<br>Or we can just go look<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In AppDelegate right click on &#8220;Application&#8221; in the line<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\tpublic class App : Application\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and select &#8220;Goto definition&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"410\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.07.28-PM.png?resize=525%2C410&#038;ssl=1\" alt=\"\" class=\"wp-image-1409\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.07.28-PM.png?w=900&amp;ssl=1 900w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.07.28-PM.png?resize=300%2C234&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.07.28-PM.png?resize=768%2C599&amp;ssl=1 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">There s a lot of stuff in here. But what we want so see is which methods are declared <strong><em>PUBLIC VIRTUAL<\/em><\/strong>. Why ? thee are ones that are defined to be implemented in a subclass. They are quite literally meant to be overridden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And there are several of interest to us right now<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>protected virtual void Opened ()\n\nprotected virtual void Opening ()\n\nprotected virtual void Closing ()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There are others but these are the ones we care about right now<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Opening is called right after the application instance is created. This is usually before anything else is seen.<br>Opened is called when the application has successfully started.<br>Closing is called before the app closes.<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So since we want to attach out menu when the app is about to show its first window we&#8217;ll implement Opening. Copy the declaration and paste it into <em>AppDelegate.cs<\/em> after the existing App method. And yes type in a {} following it to indicate the method has no code yet.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"371\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.16.33-PM.png?resize=525%2C371&#038;ssl=1\" alt=\"\" class=\"wp-image-1410\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.16.33-PM.png?w=672&amp;ssl=1 672w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.16.33-PM.png?resize=300%2C212&amp;ssl=1 300w\" sizes=\"auto, (max-width: 525px) 100vw, 525px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">One thing we need to do is alter the signature of the method to lets the compiler know that our application subclass has overridden the super class Opening event. To do that we need to change the VIRTUAL to OVERRIDE in the method signature.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"137\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.25.17-PM-2.png?resize=525%2C137&#038;ssl=1\" alt=\"\" class=\"wp-image-1413\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.25.17-PM-2.png?w=938&amp;ssl=1 938w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.25.17-PM-2.png?resize=300%2C78&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.25.17-PM-2.png?resize=768%2C201&amp;ssl=1 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><br>To add the menu to our application its one line of code<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      NSApplication.SharedApplication.MainMenu = new AppMenu(\"Test\");<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note there are STILL no attached menu handlers ; but if you run and select the application menu you should see there IS a Quit menu item there<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"92\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.27.42-PM.png?resize=525%2C92&#038;ssl=1\" alt=\"\" class=\"wp-image-1414\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.27.42-PM.png?w=628&amp;ssl=1 628w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.27.42-PM.png?resize=300%2C53&amp;ssl=1 300w\" sizes=\"auto, (max-width: 525px) 100vw, 525px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For the Quit menu item we&#8217;re going to add that one to the Application &#8211; unlike others which might need to be attached to a specific window or control.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To do this we write whatever method we want to be called when the quit menu item is selected. And then we tell the application what menu item should call this method when we select it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First lets write the method to call when the menu item is selected.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can, quite literally, name it just about ANYTHING we want. But, picking good names is useful so we&#8217;ll create a method in the <em>AppDelegate.cs<\/em> named <em>QuitMenuitem_Action<\/em> which I hope is indicative of what this will do \ud83d\ude1b <br>This method doesnt return anything, so its return type should be <em>void<\/em>.<br>It DOES get called with two parameters &#8211; one, the <em>sender<\/em>, which is of type object, and the event arguments, of type <em>EventArgs<\/em>.<br><br>So our method signature should look like<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  void QuitMenuItem_Action(object sender, EventArgs e)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">followed by a pair of empty { }<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And the ONLY code that needs to be in here is a call to, you guessed it, Quit<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void QuitMenuItem_Action(object sender, EventArgs e)\n{\n      Quit();\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To make it so the App menu item, Quit, runs this code when the item is selected we ned to attach the two. It makes sense to do this in the same spot we created the menu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want you can look in the definition of Application again. <br>There you will see that Application has a dictionary of menu handlers.<br>The <em>key<\/em> is the menu item, and the <em>value<\/em> is the method to call.<br>So we can set the Application.MenuHandlers using code like<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> MenuHandlers = new Dictionary&lt;MenuItem, EventHandler&lt;MenuEventArgs>>()\n {\n   { AppMenu.QuitMenuItem,  QuitMenuItem_Action}\n };<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This few lines is VERY dense but we can make sense of it<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>MenuHandlers<\/em> is a property on Application we&#8217;re going to set to<br>a <em>new<\/em> <em>Dictionary<\/em><br>But what&#8217;s all the rest of <em><strong>&lt;MenuItem, EventHandler&lt;MenuEventArgs>><\/strong><\/em> ?<br>The difference here, unlike Xojo, is that we can EXPLICITLY TYPE what the <em>key<\/em> and <em>value<\/em> MUST be. Xojo&#8217;s dictionary only uses variants so strong typing of dictionaries isn&#8217;t possible. C# directly supports strong typing of the keys &amp; values.<br>So this <em><strong>Dictionary&lt;MenuItem, EventHandler&lt;MenuEventArgs>><\/strong><\/em> says we are creating a dictionary that uses <em><strong>MenuItem<\/strong><\/em> for keys and the values are <em><strong> EventHandler <\/strong><\/em>that get <em><strong> MenuEventArgs<\/strong><\/em> as their parameters. Absolutely unambiguous what can go in there.<br><br>And the following <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> { AppMenu.QuitMenuItem,  QuitMenuItem_Action}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">adds one item to that dictionary with the Quit menu item as the key and our brand new method we just wrote as the menu item handler.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"460\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.48.24-PM.png?resize=525%2C460&#038;ssl=1\" alt=\"\" class=\"wp-image-1415\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.48.24-PM.png?w=950&amp;ssl=1 950w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.48.24-PM.png?resize=300%2C263&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-5.48.24-PM.png?resize=768%2C673&amp;ssl=1 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now if you run and select Quit from the application menu your app should now quit.<br>Simple stuff to do in Xojo &#8211; and it is here as well but the explanation of how this all works takes time &amp; images \ud83d\ude42<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And now as promised<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ADDING CONTROLS !!!!!!<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can close the AppDeletage now as we dont need to make any more changes there for now.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Adding controls &amp; event handlers is all done in the MainWindow.cs we created before. Open that now.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Just like with Application where we perused the framework class to see how things worked we&#8217;ll go look at the <em>Window<\/em> class. This class is MUCH more complex than the last we looked at. But again we are looking for protected virtual methods that are ones we can override to add functionality to our Window subclass.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The one we will override is<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>protected virtual IEnumerable&lt;Control> SetupControls ()\n{\n    return new Control&#91;0];\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The implementation in place creates an empty array of controls. Copy the declaration and we&#8217;ll paste that into our Window subclass.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"322\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-6.32.05-PM.png?resize=525%2C322&#038;ssl=1\" alt=\"\" class=\"wp-image-1416\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-6.32.05-PM.png?w=947&amp;ssl=1 947w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-6.32.05-PM.png?resize=300%2C184&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-6.32.05-PM.png?resize=768%2C471&amp;ssl=1 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Again we need to change <em>virtual<\/em> to <em>override<\/em> so the compiler knows we&#8217;re stating this method overrides the one in the baes class.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In our Window we will usually, but not always, want to declare a variable to hold a reference to a control. If we want to refer to that control in other code, event handlers, etc it&#8217;s easier to keep a reference to the control than it is to dynamically find it on the layout all the time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So we&#8217;ll add a property to our subclass<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> TextField textfield;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;d put this declaration right after the declaration of the subclass<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"230\" src=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-6.39.20-PM.png?resize=525%2C230&#038;ssl=1\" alt=\"\" class=\"wp-image-1417\" srcset=\"https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-6.39.20-PM.png?w=785&amp;ssl=1 785w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-6.39.20-PM.png?resize=300%2C131&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.great-white-software.com\/blog\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-29-at-6.39.20-PM.png?resize=768%2C337&amp;ssl=1 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Note that we CAN also alter the visibility of this by prefacing it with private ( or any of the many others that exist in C# https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/accessibility-levels) Public, protected and private are all very similar to how Xojo uses them. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The code in SetupControls then has to create the control with its initial set up and add it to the window.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Creating a new control is about what you would expect. You use the NEW keyword and the classname. You can browse the framework to see what constructors are available. Some controls have several. Most however have a nice easy one that takes 4 coordinates for the left, top, width and height. We&#8217;ll use that one :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   textfield = new TextField( 10, 23, 80,  23);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And we can also fill the field with some text<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   textfield.Text = \"not edit no select\";<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And now we just have to return the right kind of item. <br>IEnumerable is an INTERFACE &#8211; exactly like in Xojo.<br>And it just so happens that an array implements that interface !<br>So we can return a new array of controls like<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  return new Control&#91;] { textfield };<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now if you run you will find you can edit the text in the textfield.<br>Cut copy and paste wont work just yet as there is no EDIT menu and the OS relies on that existing to make the textfield work as expected. <br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;ll leave adding that as an exercise \ud83d\ude42<br><br>Tinker around and see what other control you can work with and test things out.<br>Note theres lot there but not all are 100% complete <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The<a href=\"https:\/\/great-white-software.com\/miscellaneous\/CSharp\/getting_started-2022-09-29.zip\"> project so far<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For all of you following along YEAH its about damned time ! \ud83d\ude42I agree I&#8217;ve been proceeding slowly to make it so you can follow and not try to cram 10000 items in one post (we ARE trying to keep it manageable) First Lets remove the last bits of &#8220;cruft&#8221; left in our getting starting &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.great-white-software.com\/blog\/2022\/09\/29\/adding-menubar-controls-in-c\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Adding menubar &#038; controls in C#&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1],"tags":[34],"class_list":["post-1401","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-csharp"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/posts\/1401","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/comments?post=1401"}],"version-history":[{"count":1,"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/posts\/1401\/revisions"}],"predecessor-version":[{"id":1418,"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/posts\/1401\/revisions\/1418"}],"wp:attachment":[{"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/media?parent=1401"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/categories?post=1401"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.great-white-software.com\/blog\/wp-json\/wp\/v2\/tags?post=1401"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}