I'm trying to build a Monogame view inside a RelativeLayout from my MvvmCross monodroid Activity view.
An android Activity inherits from Microsoft.Xna.Framework.AndroidGameActivity to be able to run a Monogame inside a RelativeLayout (working).
My MvvmCross Activity inherits from MvxBindingActivityView(working).
So, I need a way to run the game and bind some datas within the same activity.
Thanks in advance for your help.
Loosely speaking, you can translate any Activity to an MvxActivity by inheriting some interfaces and by then cutting and pasting a small amount of code which does the basic loading and assignation of the ViewModel.
e.g. see the #Region and IMvxAndroidView<TViewModel> added to make MvxActivityView.cs from a normal Activity.
e.g. it's the same region and interface used for adapting a specialised Activity like Google's MapActivity into MvxMapActivityView.cs
At this level, the Activity/View has a ViewModel which can be used in C# code, but has no clever xml inflation - it has no clever Binding support.
Code can be written at this level - I've shipped apps without binding - but many users prefer to add DataBinding too...
To add this DataBinding support, you need to add a bit more code which provides BindingInflate, storage of bindings, disposal of bindings, etc.
e.g. a raw MvxActivityView is extended using the IMvxBindingActivity interface and a #region like: MvxBindingActivityView.cs
e.g. MvxMapActivityView is extended using the same region and interface: MvxBindingMapActivityView.cs
So to extend your the custom AndroidGameActivity:
Inherit from AndroidGameActivity to get ViewModelOwningGameActivity<T> and cut and paste the IMvxAndroidView<TViewModel> interface and #region from MvxActivityView<T> to provide the ViewModel methods, fields and properties.
Then assuming you want binding:
Inherit from ViewModelOwningGameActivity<T> to get BindingGameActivity<T> and cut and paste the IMvxBindingActivity and #region from MvxBindingActivityView<T> to get the binding methods
For specialist Activities you may want to add more - e.g. you may could add some custom helper methods for the MapActivity to plot points and lines, or for GameActivity to do whatever games do... but this is up to individual implementations.
Sorry about the cut and paste of code required in adapting Activities - I have tried to keep this to a minimum. However, writing Mvx is the one time so far that I've really wanted Multiple Inheritance or Mixins in C#
Related
When creating a WatchKit (WatchOS) Interface controller in the storyboard designer/editor, I cannot set it's class to something that is not itself type WKInterfaceController nor an immediate derived child of WKInterfaceController.
Basically in the hope of abstraction and better code reuse, better design overall, I would like to be able to use classes that are how to say, a more distant relative of their base WKInterfaceController
Basically right now it seems that your stuck using the storyboard designer to make a new WatchOS project. And using the storyboard designer you only have the option to select the WKInterfaceController class:
public partial class WKInterfaceController
or one that directly inherits from it:
public partial class ChildInterfaceController : WKInterfaceController
but nothing else such as:
public partial class GrandChildInterfaceController: ChildInterfaceController
So is there any way to do this that doesn't risk the chance of getting corrupted when you reenter the storyboard designer at some point?
Note: I've already asked if it is possible to avoid using a storyboard all together, but that has gone unanswered so I'm assuming no.
For clarity I'm talking about this dialog for "class":
I'm developing an Xamarin Android Mvx5-beta application. When running on a small-screen device, I want to show a drawer navigation using the Toolbar and the hamburger-icon. On larger devices, e.g. tablets, I want a different layout conaining three columns. No drawer navigation but a static panel with navigation options and two other panels for content.
I started with the examples XPlatformMenus and Fragments to get a drawer navigation layout combined with the use of activities (with fragments) in different layouts qualifiers, like:
Question:
Using this approach, Android automaticly looks for an activity with the same name (e.g. main_activity.axml) in the appropriate layout-qualifier folders. But on the larger screens I don't need a drawer layout and I do need an extra column. The Mvx-viewmodel does not yet know what layout to render, so it just calls:
ShowViewModel<HomeViewModel>();
ShowViewModel<MenuViewModel>();
These ViewModels, for example MenuViewModel, are registered for fragments that require a navigation_frame, as shown in here:
[MvxFragment(typeof(MainViewModel), Resource.Id.navigation_frame)]
[Register("mydemoapp.droid.views.fragments.MenuFragment")]
public class MenuFragment : MvxFragment<MenuViewModel>, NavigationView.IOnNavigationItemSelectedListener
{
<..>
}
So, rendering this same Activity in layout-sw600dp requires a navigation_frame. Which I don't want on these larger displays.
What would be the preferred design choise in this situation? I can think of two:
Show/hide elements in the Activity programmatically by querying the screen info
Don't make use of layout qualifiers, but design complete seperate Activities for larger screens and based on screen size let MVX Show ViewModel-A or ViewModel-B.
Any advice would be appreciated, many thanks in advance.
I think it depends how different your layout need to be between large screen and small screen form factors.
Few UI differences
In addition to using different layouts, you can define a bool property in your XML values resources that is different between standard and sw-600dp
values
<bool name="is_large_screen">false</bool>
values-sw600dp
<bool name="is_large_screen">true</bool>
You can then read this value in your Android views and prevent methods like ShowViewModel<MenuViewModel>(); firing when on large screens by altering the method calls from the view.
Many differences/Structural differences
If they share the same business logic but have very different UI requirements and you want to keep large screen code separate. Then I would suggest sharing the ViewModels but creating two separate Activites and layouts to handle the UI presentation. Using this method requires a bit more setup as you have to override some default MvvmCross behaviors as by default you can not register multiple Activities/Fragments to the same ViewModel. Overriding the MvxViewModelViewTypeFinder view lookup FindTypeOrNull you can intercept the lookup and filter types base on naming conventions. For example all large screen views end with "Tablet". Using the is_large_screen bool you can flag which views to register.
I want to detect the scroll of tableview in my class. I used decelerationEnded method of UITableViewDelegate but it got crashed.
Ideally you should be using a UITableViewSource assigned to your UITableView.Source property. You no longer require a delegate class, you can override all of the necessary methods within the source, which is the currently preferred method of achieving the result your after. You are most likely looking to override the method called 'Scrolled' within the UITableViewSource. However I would suggest making use of 'DecelerationEnded' as well if you're trying to do something depending on if your scroll view is at the 'bottom' or 'top' of the UITableViews content (That's just a little tip based off of some experience with this in a recent project.)
I have question whether it is possible somehow use this project structure and within some ViewModel navigate to specific View from Core.Windows/Core.WindowsPhone.
1. PCL libraries
Core (PCL for universal apps)
ViewModel
Core.Windows (PCL) - reference to Core
View
Core.WindowsPhone (PCL) - reference to Core
View
I need to keep View in PCL because I use the same View for some other projects.
2. Universal app
Windows - reference to Core, Core.Windows
WindowsPhone - reference to Core, Core.WindowsPhone
Shared
Yes I think it is possible.
I have a similar requirements in my solution (using same View for different apps)
Basicly I suggest the following:
1) Create a NavigationService abstract class and/or INavigationService interface in Core (PCL for universal apps with ViewModels).
2) Create WindowsNavigationService and WindowsPhoneNavigationService classes in Core.Windows and Core.WindowsPhone which derive from NavigationService in 1)
This classes can do the following:
1) Hold an instance of
Dictionary<ViewModelBase,Page> mapDictionary
ViewModelBase is a base class for your viewmodel (I suppose you have one).
2) Register the data in mapDictionary: e.g. add View and corresponding ViewModel to it
3) Perform navigation buy holding the instance of Frame: e.g. NavigateTo, GoBack and so on
4) Bind the ViewModel to View.
After that you can Hold a NavigationService in your ViewModels and perform navigation between them.
If you are interested in such approach I suggest to waste some time and take a look at https://github.com/MvvmCross/MvvmCross - this can give you ideas about how you can build your architecture.
Also interesting post about PCL (with sample code demonstrating described approach): http://msdn.microsoft.com/en-us/magazine/hh852593.aspx
Source code for the article: http://download.microsoft.com/download/6/2/D/62D36C65-4C36-429A-8711-F657D34AB4BC/Code_KeanPCL0312.zip
In many occasions JavaFX needs to be customized with classes that extend existing ones. I tried this approach, for example to add a method to the NumberAxis class that would enable the label of the axis to be rotated.
But I got a "NumberAxis is declared final, can't be extended" compiler error. I wonder how people who extend classes do? Do they have access to the source code of javafx, modify it to make some classes not final, and recompile it? (sounds tricky! )
Making lots of classes final in the JavaFX framework was an intentional decision by the framework developers. To get a flavor of why it's done, see the Making Color Final proposal. That's just an example, there are other reasons. I think experience with subclassing in the Swing framework was that it caused errors and maintenance issues that the JavaFX designers wanted to avoid, so many things are made final.
There are other way to extend functionality than to directly subclass. Some alternatives for your rotation example:
aggregation: include the NumberAxis as a member of new class (e.g. NumberAxisWithRotatableText) which adds an accessor to get the underlying NumberAxis node and a method to perform the rotation (e.g. via a lookup as explained below).
composition: for example extend Pane, add a NumberAxis, disable the standard text drawing on the axis and add rotated labels yourself as needed.
css stylesheet: for example use a selector to lookup the text in the NumberAxis and the -fx-rotate attribute to rotate it.
node lookup: Use a node.lookup to get at the underlying text node, and apply the rotation via an API.
skin: All controls have a skin class attached them, replace the default skin class with a custom one.
subclass an alternate class: Subclass the abstract ValueAxis class rather than the final NumberAxis class.
Source code for JavaFX is available with build instructions. However, I don't recommend hacking a personal copy of the source code to remove final constructs unless you also submit it as an accepted patch to the JavaFX system so that you can be sure that your app won't break on a standard JavaFX install.
If you really think it is a good idea for a given class to be subclassable, then log a change request. Sometimes the JavaFX developers are overzealous and make stuff final which would be better not being final. NumberAxis perhaps falls into that category.