Xamarin Forms with MvvmCross 5.7 First View not loaded - xamarin.forms

I have an Xamarin Application together with MvvmCross 5.7 and wanted to moved it completly to Xamarin Forms. It builds and starts as expected, but the first page isn't loaded.
I created the projects based this template: https://github.com/martijn00/MvxForms
Also I created a test project to see if something is wrong with my existing project: https://github.com/NPadrutt/XFTestProject
Can anyone point out what I am missing?

Either add a SplashScreen Activity who inherits from MvxSplashScreenActivity and with the method override:
protected override void TriggerFirstNavigate()
{
StartActivity(typeof(MainActivity));
base.TriggerFirstNavigate();
}
Or add these lines to the OnCreate Method in the MainActivity:
var startup = Mvx.Resolve<IMvxAppStart>();
startup.Start();
InitializeForms(bundle);

You don't neet to call startup.Start() in your MainActivity nor you need to init xamarin forms. It's done for you now (check RunAppStart method in mvvmcross sources for MvxFormsAppCompatActivity class).
From a quick glimpse at your GitHub repo, it looks like you're not decorating your view (i.e. WelcomView) with [MvxContentPagePresentation()] attribute (e.g. example from MvvmCross Playground). Add it in your WelcomeView.xaml.cs file and check if that helped
If it's a fresh project, you might want to consider using latest version of MvvmCross (v6). There's an awesome step by step guide to setup Xamarin.Forms with it by Nick Randolph

Related

How to use Toucheffect in Maui. In xamarin forms we can do it using the xamarin toolkit.

This is the shared touch effect files
This is the android platforms specific code
This is where I register the effect and the handler
This is where I used toucheffect nativeanimation property
Some properties are working , for example : the PressedOpacityBackgroundColor. Is there a way to make the native animation property to work
I tried from someone's code from where this issue was mentioned. I implemented as it is but the native animation property isn't working and also some other properties as well.
You can also use the Toutheffect in the MAUI.
You can add the Xamarin.CommunityToolkit.MauiCompat 2.0.2-preview1013 to your project. It is the .NET MAUI Compatible version of Xamarin.CommunityToolkit.

MVVMCross BindingContext is Null when not using MvxContentPage

I have an issue where several of my pages are using the SfBackdropPage control from Syncfusion. This control requires the page to have a base of SfBackdropPage and not the usual ContentPage otherwise it just won't work.
To make MVVMCross work, the page needs have a base such as MvxContentPage
You see where this is going ?
I opened a ticket with Syncfusion to see if they could work around this issue but basically they just said its not possible. So since I needed to have that control as part of the page I had to leave the base as it was.
How do I setup MVVMCross to work with these pages without having the page inherit from MvxContentPage ?
I've used the following in the setup.cs in the Android project:
protected override IMvxViewsContainer InitializeViewLookup(IDictionary<Type, Type> viewModelViewLookup)
{
viewModelViewLookup.Add(typeof(SitesViewModel), typeof(SitesView));
return base.InitializeViewLookup(viewModelViewLookup);
}
I can navigate to the page but I get a null reference exception due to the binding context not been set. I've tried to set this in the XAML but it requires a parameterless constructor but that's not possible as the view model uses Dependency Injection as it relies on these object been passed in.
Can anyone give any pointers, I'm still learning MVVMCross so hopefully I've just missed something.
XF: 4.8.0.1687
MVVMCross: 7.1.2
UPDATE 1:
I've tried to find something in the MVVMCross source to see how it does the setup for the binding context, but I've not found anything. So for now, I'm manually creating the binding context in the page code behind and using Mvx.IocProvider.Resolve<> to pass the required interfaces.
I'm not sure if this is the best to workaround this issue but it works. Maybe there is a better way ?
UPDATE 2:
It seems that update 1 route is no good as the doing this creates a new instance of the VM which is to be expected but an instance already exists which is created by the MVVMCross framework. The question is how do I get the VM instance from the code behind ? The only way I have found so far is to use IMvxOverridePresentationAttribute and the cast the request to MvxViewModelInstanceRequest which then allows access to the VM instance which I assign to the binding context. I may be better off creating another question as to the best approach for this method.

Xamarin Forms Prism Naming convention with subfolders

Is there a standered naming convention when making folders in a prism project ?
This works
ViewModals:
HelloWorldPageViewModel
View:
HelloWorldPage
App:
Container.RegisterTypeForNavigation<Views.HelloWorldPage >();
But for some reason , this does not work
I added the folling folders Login > Template >
ViewModals:
Login.Template.HelloWorldPageViewModel
View:
Login.Template.HelloWorldPage
App:
Container.RegisterTypeForNavigation<Views.Login.Template.HelloWorldPage >();
You have three options:
Change the naming conventions using the ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver. You can see an example in this blog post: http://brianlagunas.com/getting-started-prisms-new-viewmodellocator/
Or you can simply register your VM directly with ViewModelLocationProvider.Register<View, ViewModel>();
If you are using Xamarin.Forms simply provide the VM in the Container.RegisterTypeForNavigation<View, ViewModel>(); method
To the best of my knowledge Prism checks namepaces of ViewModels and Views.
So if your have a view it has to be under Views.Something , and if you want to have a viewmodel for it should be "ViewModels.SomethingViewModel"

Can I automatically generate controller classes from FXML?

As I understand it, when using FXML to describe a Java FX scene, the controller class is written manually and it's member variables and methods can then be referenced from the .fxml file. When loading the scene using the FXMLLoader, member variables are set to the corresponding scene elements and methods are wired up to the corresponding events automatically. This works but is very cumbersome as changes need to be done in two places and any mistakes will only show up at runtime.
I've seen other GUI frameworks that allow you to instead generate the controller from a scene description as an abstract class which needs to be implemented to access the scene elements and handle the events. An example of what I mean:
I would create the following .fxml file (e.g. using the JavaFX Scene Builder):
<AnchorPane ... >
<children>
<Button fx:id="button" ... text="Button" onAction="#buttonPressed" />
</children>
</AnchorPane>
Somewhere in my build process, the following .java file would be created (e.g. using a Maven plugin):
abstract class TestController {
protected final Parent root;
protected final Button button;
{
// Load test.fxml file
// Assign scene elements to root and button
// Attach event handler to the button that calls buttonClicked()
}
protected abstract void buttonClicked(ActionEvent event);
}
I could then, possibly multiple times, create a concrete implementation of that controller:
final class TestControllerImpl extends TestController {
TestControllerImpl(String buttonLabel) {
button.setText(buttonLabel);
}
#Override
protected void buttonClicked(ActionEvent event) {
button.setText("I've been clicked! What a great day!");
}
}
Is there a project with the goal to do this? Or is there a problem with this approach applied to FXML?
I see the following benefits from this approach:
Declarations for member variables and methods for the controller are automatically generated.
All member variables are final and protected instead of non-final and either public or annotated.
The same for methods, they are protected instead of either public or annotated.
Not implementing a method or misspelling it's name will lead to a compiler error.
Programmatic setup of the scene can be done in the constructor instead of an initialize() method because the constructor will run after the scene has been loaded and its elements assigned to the member variables.
This is now supported in SceneBuilder, NetBeans and in Eclipse. Note this works out of the box in NetBeans and SceneBuilder, but in Eclipse you first need the e(fx)clipse plugin.
SceneBuilder:
With an FXML file open in the editor, enter the menu to select "View" and "Show Sample Controller Skeleton".
Eclipse:
Open the fxml file so the contents are displayed in the code editing pane (you should see the fxml as plaintext xml with syntax highlighting inside Eclipse, not rendered visually in SceneBuilder). Right-click on the code in Eclipse and select "Code" and then "Generate Controller".
NetBeans:
In NetBeans it is even easier, right-click the fxml file in the project explorer and select "Make Controller".
Update Nov 2020
This answer is now outdated.
As various more recent answers have pointed out, there are now a variety of additional different tools available for automatically generating FXML controller classes from FXML documents. Many of these are targeted as extensions, features or plugins to existing development tools, such as SceneBuilder, Idea, Eclipse or NetBeans.
I suggest that interested readers review both this answer and other answers to this question, then look at their individual use-case and toolset chain and choose the solution which is most appropriate for them from the available choices.
There is nothing I know that does exactly what you propose in your question.
Likely this answer will probably end up pretty outdated over time.
Alternate Technologies
JRuby achieves most of your outlined benefits using a slightly different approach - it uses jRuby's dynamic programming magic to automatically create Ruby class members from the FXML dynamically a runtime.
Tom Schindl wrote a tool which generates Java code from FXML. Of the approaches listed in this answer, Tom's tool seems closest to your question.
SceneBuilder Skeletons
A similar Java code generator from FXML is available in SceneBuilder View | Show Sample Controller Skeleton feature, which is described in this blog post. When I use SceneBuilder, I use this feature all the time and try to keep my controllers really light so they are almost all auto generated code from the SceneBuilder skeleton feature.
It is slightly annoying though because it doesn't achieve a clean separation of generated code from hand written code, so you need to be careful when you do updates to the FXML and want to generate a new skeleton and copy and paste it over parts of your existing Controller (plus that is a slightly error prone manual operation that takes a little bit of developer time).
Source code for SceneBuilder is available if you want to see how it works.
Potential Build Tool Plugins
Such a code generation feature might make a worthwhile addition to some of the existing build tools in the JavaFX ecosystem, such as the JavaFX Maven plugin or JavaFX Gradle plugin (or a separate plugin in it's own right).
Future Development
I believe that Oracle are also working on a feature extension for FXML for a future JavaFX release (post Java 8) which compiles FXML directly to Java byte code (class files), bypassing the Java source code step. This kind of feature would probably achieve most of your outlined benefits.
It is possible with NetBeans version 8.
Open FXML , go to Source and click generate controller.
Edit: Now can be done in any IDE , Eclipse needs a plugin thought.
For Intellij Idea IDE users, FXMLManager to the rescue. See the plugin homepage
"When clicking right mouse button on .fxml file, there is new menu item "Update Controller from FXML".
Clicking this item will modify FXML Java Controller:
Remove all #FXML fields that are missing in FXML and their getters/setters
Add all #FXML fields that are missing in Controller
#Deprecate all ActionEvent methods that are missing in FXML
Create all ActionEvent methods that are missing from Controller"
As I know, there are two kind of solutions exist in netbeans.
First, netbeans's internal feature "Make Controller", which you can see with right mouse click on the fxml document. it will generate controller class which will work with FXMLLoader. The controller's java file name should be indicated in the fxml document. (left panel -> Controller -> Controller class)
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Second, netbeans's plugin "FXML 2 JAVA Converter", which you can install from menu (Tool -> Plugin -> Available Plugin -> FXML 2 JAVA Converter). and you can see "Generate Abstract Class" menu item with right mouse click on the fxml document. It will generate source code from fxml document and you can use it as an abstract class without using FXMLLoader like normal JavaFX project not JavaFXML project.
Now you can easily do it with eclipse Just do these simple steps :
Go to your fxml file that you want to create Controller for
Right Click and Click source
Click Generate Controller
Click here to see the Picture of How to do it.
If you're using IntelliJ ide, you may have to try FXML Helper plugin.
First, install the plugin from the File | Settings... | Plugins. After the installation restart the ide, Now right click on the .fxml document and select the FXML Helper menu. That`s all.
#Feuermurmel
no there is not any ways to generate automatically controller class for particula .fxml file.
you should define dynamically declare variable and method with anotation #fxml and set(bind) in scence builder.

adding implementation and header files

Hi all i have created my code etc for the .h/.m that are all ready provided. But i would like to known how to add more because when i add a view controller to my storyboard. I can't have code in it i think what I'm looking for is called a second view controller .h/.m. I am creating a project in Xcode 4.2 and its a single view based application. I'm new to this but i think what i have said makes sense thanks for your time.
kind regards
open your project
press command+N to open the new file dialog
iOS > CocoaTouch
Class = YOUR_CLASS_NAME
Subclass of = SUBCLASS_TYPE (e.g. UIViewController)
etc.

Resources