I come from a very proficient Windows .NET background and I'm having a go with Monotouch and I am very confused as to how to respond to events. I like to keep things simple and I have read the Montouch tutorials and looked at the examples. What I'm getting confused about is how to respond to events.
Lets say I have ViewController with a UIButton and a UILabel on it. When I press the button I want to change the label to say "Clicked button".
Therefore I could just do the following:
public override void ViewDidLoad () {
base.ViewDidLoad ();
this.btnClickMe.TouchUpInside += (sender, e) => {
this.lblOutput.Text = "Clicked # " + DateTime.Now.ToShortTimeString ();
}
OR alternatively, I could use this approach which I think would serve me better when it comes to responding to buttons pressed in NavigationBars etc.. In IB I Ctrl-Drag to create an Action. I then move the [Action] method to my .cs file and do the following.
[Action ("btnClickMe_TouchUpInside:")]
public void btnClickMe_TouchUpInside (NSObject sender)
{
this.lblOutput.Text = "Clicked # " + DateTime.Now.ToShortTimeString ();
}
What makes it more confusing for me is some UI components have a .delegate member. To which I can an add an event.
Whats the best method or am I getting totally confused? If so is there is a link you can direct me to where I can learn the best practice, the right approach etc..
Many thanks
Mike
For a good introduction, I recommend Xamarin's article on Events, Protocols and Delegates.
As far as your question of wiring up Action Outlets versus hooking events to Referencing Outlets, they have this to say:
The main difference between using .NET events as opposed to
target-actions is that the latter allows you to wire up multiple
controls to a single action method.
So, you might be inclined to use the action approach if you were building a quick & dirty calculator, and pressing the numbers 0-9 all do the same thing-- you can just read the digit from the button. (If you ever used VB to create a control array, you might be familiar with this technique.)
That said, I find my personal preference is to stick with Reference Outlets. It requires less thinking and going back & forth between MonoDevelop and the Interface Builder. I drop in a UISlider & reference it, then I have access to all of its properties & events from the code. So, hooking something later can be done from the code. Many developers have commented that they trend away from using IB...
Getting back to the facts, MonoTouch offers multiple redundant ways to interact with the UI. For those coming from Objective-C, you will find the familiar "Objective-C Delegates" and references to "selectors". Coming from C#, you can often ignore those approaches. But, you should take the time to read that article so you'll be familiar with the language used in Apple documentation. For example, it is important to note the difference between "Objective-C Delegates" and "C# delegates".
Delegates are used for callbacks in iOS similarly to the way .NET uses
events. To make iOS APIs and the way they use Objective-C delegates
seem more like .NET, MonoTouch exposes .NET events in many places
where delegates are used in iOS.
In time, I believe you will find the API flexible and accommodating of .NET patterns. Converting between the NS types and .NET types is often transparent (e.g. from a lambda expression to an NSAction).
Let me know if you need more specific information.
Cheers.
Related
I have recently started experimenting with Xcode following the introduction of Swift. I have no background in Objective C, but I am making progress, especially with Cocoa Bindings and Core Data. I am playing around with an OSX application which has one xib and one window and is bound to a Core Data model. So far everything works just fine and I can populate a Table View with no issues.
My next step is to include a second window with another Table View bound to my Core Data model. I found this impossible to achieve because I couldn't access the AppDelegate when I tried to bind the second Table View to the Core Data model.
So I tried to create a second window in the MainMenu xib; now binding is possible but it seems to be very clumsy. Surely a second window demands its own xib and, if so, how on earth do I bind to the AppDelegate?
My goal is to use Coocoa Bindings as far as possible to eliminate "glue code", but all my research only reveals Objective C examples, some of which are very old, involve a huge amount of program code and are not at all relevant to Xcode v6.1.
I'm a newbie to Xcode, but so far I love it and would appreciate any advice or assistance.
The single-coordinator application template adds that "App Delegate" object to the MainMenu.Xib, and it's somewhat magically connected to the NSApplication object's delegate, in that the App Delegate object is created by the Nib loading process and attached to the NSApplication instance. It's fairly impossible to duplicate that object in another Nib. You can really create havoc trying to do so.
The simplest way to do what you want in any other Nib is to bind to the Application with a keypath beginning with "delegate." Voila, you have what you want.
Others will insist that the delegate object shouldn't own the core data stack, and you should move all that boilerplate code to some other place. Or, that each view controller should be passed the MOC pointer as a property (see comments below)... but that's not really relevant to this question.
YMMV, this answer is given from the Objective-C universe, but the language shouldn't matter.
The generated designer.cs properties are private by default (at least without manual tweaking of generated code). This makes coding against something like a UITableViewCell feel much different than if I were doing this in Objective-C.
The popular way in the case of UIxxxViewCells, at least from what I can tell, is for the UIxxxViewDataSource to populate the IBOutlet properties, and that the cell should only be responsible for anything related to drawing/rendering the view.
With Xamarin.iOS, we are unable to access these properties from the data source, and instead are required to provide additional setter methods to populate the cell. In this way, the cell is responsible for setting it's own properties.
Is this just "The .NET way" of doing things?
It's so that we don't break encapsulation by default.
The outlets belong to the object they're on, it should be able to choose whether they're able to be modified from the outside. The fact that they're properties is an implementation detail of the Xamarin.iOS outlets system - you should think of them as private fields.
If you wish to expose them, you can create properties that do so - preferably read-only.
It was probably done that way because that's how the other GUI designers in MonoDevelop worked at the time (still do). Auto-generated bindings to the native controls used by the user-designed control for toolkits like Gtk# are also created as private.
I'm not sure if other UI designers for .NET work (I've never used Visual Studio to develop GUI apps using Windows.Forms or WPF).
Feel free to file a feature request on https://bugzilla.xamarin.com to make them public - I'll gladly implement it, I think it probably makes more sense for them to be public. I haven't changed it mostly because no one has expressed that they wanted it be any other way.
One of the coolest features I've seen in help viewers is the ability to hide inherited members so you can focus on only what that particular subclass offers. A good example of this is here...
http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_JsonConvert.htm
Actually, that page has various options for how to show the help, not just hiding inherited members.
Now online MSDN has a habit of just throwing everything under the sun at you meaning trying to figure out what a subclass has added, let alone getting to it requires tons of scanning and even more scrolling.
That said, is there any way, local or online, to enable those or similar features? Has anyone made an external or third-party help viewer that does this or something similar?
(Note: I'm not really sure if this is for SO since it's not a programming thing, but it is sort of an IDE-related thing so I figured I'd gamble and put it here.)
Mark
Hiding inherited items is one thing I used to miss in the Lightweight style online MSDN docs.
Fortunately, it can be easily solved by using a litte bit of in browser javascript. See How to hide inherited members on MSDN pages for details.
You should be able to expand the used principle to hide any information you need (eg. you could use the icons to tell apart the static members, methods, properties and so on...).
Updated answer for 2016:
Create a bookmark in a modern browser with the following javascript snippet as the URL:
javascript:var trs=document.getElementsByTagName('tr');var l=trs.length;for (var i=0; i<l; i++) { var tr=trs[i]; if (tr.innerHTML.indexOf('(Inherited from ')>-1) tr.style.display=tr.style.display=='none'?'':'none'; }; void(0);
Clicking this bookmark while on an MSDN class documentation page will toggle all the inherited members on and off.
The javascript is just looking through all of the table rows ('tr') on the page, finding any which contain the string '(Inherited from ', and setting their display style (visibility) to 'none'. That search string seems to cover every instance of a member being inherited.
I've looked into this quite extensively and I've found the following:
You can do some clever stuff to catch most errors by implementing a base class, see Andreas Knudsen's solution for this.
The Error event in UserControl never gets fired, see details here: http://weblogs.asp.net/vga/archive/2003/06/16/8748.aspx
What I can't find is any general way to catch errors occurring in postback events, such as the click event for a button, at the web part or user control level. What I mean by general is a something I can implement in a baseclass.
I'm aware the I should do proper try/catch in my code, but for large teams I'd like to be sure that a web part never crashes the page, but always shows a nice message and allows execution to continue for the other web parts on the page.
I don't think it's possible but I'd love to be proved wrong.
Thanks,
Bjoern
I think this is possible, but you have to work around the fact that when asp.net distributes the postback events it couldn't care less about your user control definitions, instead it only cares about controls that explicitly implement IPostBackEventHandler (like button / dropdown etc)
For pages you can override and try/catch RaisedPostBackEvent like for the other methods. (if you ever wanted a generic page-exception handling setup. (if you want this then please reconsider. I spent way too much time in my last project basically reimplementing the default asp.net exception handling logic just to get this to work. the devil's in the details)
What you could do is to have a base page in your system which all pages inherit from and which overrides RaisePostBackEvent(source, eventArgs). In this method you could see if the source inherits from your exception handling base control, or if it is contained within a control which does this. (navigate the parent graph)
If it is contained by one then do a try/catch around the call to base.Raise.... (see the code in
Transparent generic exception handling for asp.net / MOSS2007 (with code) ) and call the exceptionhappened method on the first candidate you found if indeed any exceptions occur.
Background
I'm going to develop a new web-application with java. It's not very big or very complex and I have enough time until it'll "officially" start.
I have some JSF/Facelets development background (about half a year). And I also have some expirience with JSP+JSTL.
In self-educational purpose (and also in order to find the best solution) I want to prototype the new project with one of action-based frameworks. Actually, I will choose between Spring MVC and Stripes.
Problem
In order to get correct impression about action-based frameworks (in comparison with JSF) I want to be sure that I use them correctly (in a bigger or a lesser extent).
So, here I list some most-frequent tasks (at least for me) and describe how I solve them with JSF. I want to know how they should be solved with action-based framework (or separately with Spring MVC and Stripes if there is any difference for concrete task).
Rendering content: I can apply ready-to-use component from standard jsf libraries (core and html) or from 3rd-party libs (like RichFaces). I can combine simple components and I can easily create my own components which are based on standard components.
Rendering data (primitive or reference types) in the correct format: Each component allow to specify a converter for transforming data in both ways (to render and to send to the server). Converter is, as usual, a simple class with 2 small methods.
Site navigation: I specify a set of navigation-cases in faces-config.xml. Then I specify action-attribute of a link (or a button) which should match one or more of navigation cases. The best match is choosen by JSF.
Implementing flow (multiform wizards for example): I'm using JSF 1.2 so I use Apache Orchestra for the flow (conversation) scope.
Form processing: I have a pretty standard java-bean (backing bean in JSF terms) with some scope. I 'map' form fields on this bean properties. If everything goes well (no exceptions and validation is passed) then all these properties are set with values from the form fields. Then I can call one method (specified in button's action attribute) to execute some logic and return string which should much one of my navigation cases to go to the next screen.
Forms validation: I can create custom validator (or choose from existing) and add it to almost each component. 3rd-party libraries have sets of custom ajax-validators. Standard validators work only after page is submitted. Actually, I don't like how validation in JSF works. Too much magic there. Many standard components (or maybe all of them) have predefined validation and it's impossible to disable it (Maybe not always, but I met many problems with it).
Ajax support: many 3rd-party libraries (MyFaces, IceFaces, OpenFaces, AnotherPrefixFaces...) have strong ajax support and it works pretty well. Until you meet a problem. Too much magic there as well. It's very difficult to make it work if it doesn't work but you've done right as it's described in the manual.
User-friendly URLs: people say that there are some libraries for that exist. And it can be done with filters as well. But I've never tried. It seems too complex for the first look.
Thanks in advance for explaning how these items (or some of them) can be done with action-based framework.
I'll do my best to answer regarding Stripes. I've used Struts and JSF in the past, but not recently, so at best I have vague notions and feelings about them.
We are intimately familiar w/ Stripes, use it for most everything now, and really enjoy it. It is easy to jump into, supports many of the complicated scenarios, but you are also free to work OUTSIDE of it, which is really important when you want to build your own ajax widgets or talk to another system or something.
If you go the stripes route, I definitely recommend buying or download the book. It is a one stop shop for everything you need for Stripes, and is practically the only documentation for Stripersist (really nice feature, but NO web docs).
Rendering content: I can apply ready-to-use component from standard jsf libraries (core and html) or from 3rd-party libs (like RichFaces). I can combine simple components and I can easily create my own components which are based on standard components.
This is similar. Core, Html, Fmt, etc. as well as any custom tags you find, inc. display:tag, pack tag, and create your own. However, obviously you do not deal at the component level now, you deal with a tag that determines what is on the page / sent to or from the server.
Rendering data (primitive or reference types) in the correct format: Each component allow to specify a converter for transforming data in both ways (to render and to send to the server). Converter is, as usual, a simple class with 2 small methods.
Stripes has many built in converters, and it is easy to create custom converters for your more complex data types. Stripes supports very complex data structures to be mapped with little hassle. Combined with Stripersist, for example, I can put my model object directly on the ActionBean, put a few of the fields on the form, and Stripersist will hydrate the model from the db (based on its PK) and update that with the fields I put on the form - all before releasing control to me on the ActionBean.
Site navigation: I specify a set of navigation-cases in faces-config.xml. Then I specify action-attribute of a link (or a button) which should match one or more of navigation cases. The best match is choosen by JSF.
Navigation in stripes is based on what you name the ActionBeans, initially. There is no xml. Additionally, pretty urls are an annotation at the ActionBean level in Stripes 1.5, so you can do things like #UrlBinding("/{$event}/{model}") where /view/5 would take you to the "view" event handler for your Model object with the ID/PK of 5.
Implementing flow (multiform wizards for example): I'm using JSF 1.2 so I use Apache Orchestra for the flow (conversation) scope.
While I only am vaguely familiar with the concept of conversation scope, Stripes has Wizard Form functionality, but I haven't used it and am unable to really expand on that. I think it is a similar idea though.
Form processing: I have a pretty standard java-bean (backing bean in JSF terms) with some scope. I 'map' form fields on this bean properties. If everything goes well (no exceptions and validation is passed) then all these properties are set with values from the form fields. Then I can call one method (specified in button's action attribute) to execute some logic and return string which should much one of my navigation cases to go to the next screen.
Not drastically different. Instead of components on your [action] bean, you now have Java or custom types. ActionBeans are created per request and thrown away, unless you do something like put it in session, or wizard, or whatever. This is nice, because all the instance variables get mapped to the data from the form, you use it, then throw it away, and don't have to deal with any synchronization issues like struts did. After you do your thing with the data, Stripes lets you send a ForwardResolution (OK status), Redirect, or Streaming (JSON, file, etc). The Redirect-after-POST pattern is implemented nicely with the idea of flash scope (3/4 down the page).
Forms validation: I can create custom validator (or choose from existing) and add it to almost each component. 3rd-party libraries have sets of custom ajax-validators. Standard validators work only after page is submitted. Actually, I don't like how validation in JSF works. Too much magic there. Many standard components (or maybe all of them) have predefined validation and it's impossible to disable it (Maybe not always, but I met many problems with it).
Stripes allows validation in annotations on the instance variables on the ActionBean. They allow some defaults, required, maxlength, etc. or you can always create your own. The default is easy to add and flexible, while there is always the ability to make something completely customized.
Ajax support: many 3rd-party libraries (MyFaces, IceFaces, OpenFaces, AnotherPrefixFaces...) have strong ajax support and it works pretty well. Until you meet a problem. Too much magic there as well. It's very difficult to make it work if it doesn't work but you've done right as it's described in the manual.
This was my big problem with the JSF way of doing things. Even if you did get the widget right, you're still stuck with THAT widget. With Stripes, you can use whatever latest and greatest Jquery has to offer, and as long as you send the right GET or POST to the server, stripes knows what to do with it and can easily send JSON back. I think component frameworks fit a niche a few years ago much better when AJAX was hard, but JQ makes it so easy now.
User-friendly URLs: people say that there are some libraries for that exist. And it can be done with filters as well. But I've never tried. It seems too complex for the first look.
#UrlBinding, it's as easy as that.
My answer is not the one you want to hear: Don't switch from Component Framework to action framework
I switched the other way around after many years of action framework development and I'm never going back.
Of the 8 use cases you mentioned, only one comes to mind where Action frameworks are obviously better, and that is URL design / friendly URLs. It can be done in component frameworks as well, but much easier in Action Frameworks (especially in Stripes where you just annotate your ActionBean with the url).
I would advise you to try wicket, it is very easy to learn (much easier than JSF) and it let's you re-use many existing components as well.