MvvmCross android binding to fragment - xamarin

is there any way to bind in layout directly to custom fragment?
ie:
<fragment android:id="#+id/AwesomeFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
local:MvxBind="CustomTarget PropertyInVM;" class="My.Awesome.Fragment" />
CustomTarget is CustomTargetBinding

So how you can do this:
create custom control with properties you need
create target bindings
place custom control into layout instead of your fragment
bind from layout

Related

MVVMCross - Use converted value in other converter

I am trying to use two converters together in my code. One is custom, the other one is the built-in converter.
My goal is to use my converter-modified value as a parameter in another MvvmCross converter.
So, I want to get System.Drawing.Color() first via DueDateTintValueConverter, then I will give it to MvvmCross' "NativeColor" converter.
And finally, the custom binder named TintColor will handle the setting of the Android coloring.
<ImageView
android:id="#+id/imageViewWatch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="8dp"
android:tint="?attr/color_dueDate_normal"
app:MvxBind="TintColor NativeColor(DueDate), Converter=DueDateTint"
app:srcCompat="#drawable/ic_clock" />
But, I run into a binding error here getting "InvalidCastException, nullable DateTime cannot cast to Color".
It means DueDate remains the same regardless of the DueDateTintConverter.
How can I find a solution for this scenario?
Thanks!

Nested tabs views are not binding to separate ViewModel

i want to bind viewmodel to nested tab views in xamarin prism framework
i created 4 main pages(A,B,C,D) as main tabs and inside first tab(A) i created two more tabs(A1,A2).but data for nested tabs are not binding.even viewmodel for that views(A1,A2) are not hitting
MenuPage.xml
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Views.MenuPage"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
xmlns:b="clr-namespace:Prism.Behaviors;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
xmlns:views="clr-namespace:MyApp.Views"
BarBackgroundColor="White"
android:TabbedPage.ToolbarPlacement="Bottom"
NavigationPage.HasNavigationBar="True">
<TabbedPage.Children>
<views:A Title="A" Icon="abc.png" />
<views:B Title="B" Icon="abc.png" />
<views:C Title="C" Icon="abc.png" />
<views:D Title="D" Icon="abc.png"/>
</TabbedPage.Children>
</TabbedPage>
and my page A is like
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:MyApp.Views"
x:Class="MyApp.Views.A">
<!--Pages can be added as references or inline-->
<TabbedPage.Children>
<views:A1 Title="A1" />
<views:A2 Title="A2" />
</TabbedPage.Children>
</TabbedPage>
and i have separate viewmodel for A1 and A2.
so if i directly bind A1 to main navigation page it will work properly and render data.but if i do like above viewmodel for A1 is not hitting the constructor and nothing is displaying apart from static data.i am new to tabbed page navigation.any help is appreciated.this the view i am trying t achieve
I find we should add AutowireViewModel in the page's XAML to load the view model we want:
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
Generally, we use containerRegistry.RegisterForNavigation<>(); to bind the custom view model to a certain view. But you placed a sub tabbed page in the root tabbed page. This caused the nested view losing the mapping to the corresponding view model. After adding the AutowireViewModel, this issue fixed. We could still use RegisterForNavigation to bind your custom view model to your special view instead of the automatic naming conversation.
Here is my sample for a simple nested tabbed page: https://github.com/landl0526/PrismTabDemo. Refer to it for more detailed code.
Moreover, this only works on the Android platform as iOS only has the bottom aligned tabbar.

Custom Attribute of Integer on Custom View

I'm having a few problems creating an integer attribute.
So, as background. I have got a custom canvas view. I have already successfully created a custom string attribute on that. The axml looks like this:
<turbineApp.droid.infrastructure.customViews.TurbineMapCanvas
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/VicMapCanvas"
custom:mapName="VIC"
/>
And the attribute comes from attrs.xml:
<resources>
<declare-styleable name="CustomCanvasView">
<attr name="mapName" format="string" />
</declare-styleable>
</resources>
I was hoping to add an integer attribute. So, I added the following as an element in attrs.xml:
<attr name="originY" format="integer" />
But now the project won't build. At all. With a fail message that the Resources class never got built.
I've unblocked myself by just making it a string and parsing the string in the code. But why will an integer not work? Have the good people at Xamarin not implemented that yet?
Thanks

How to add a loader to a page till I get the data in the background from API in xamarin android MVVM/mono

I am able to get the data from the API which I am using it to bind the data in different ways but when getting the data is going slow, black screen is displayed for some time and then the data is getting loaded so I was trying to rectify that and make the data getting in background(async await) and then bind that to the view when the data is available locally.
How to do that?
Well basic idea is to use ActivityIndicator view which basically is a loading control in each platform. How you use it thought is different in different cases. I personally wrap content of the page in a grid like this:
<ContentPage xmlns:a="">
<Grid>
<ActivityIndicator IsRunning="True" IsVisible="{Binding IsBusy}"/>
<[The original page content]>
</Grid>
</ContentPage>
Then you create a Boolean property named IsBusy in your view model and set it to true when loading content and false after you are done.
-- Edit --
Sorry I didn't notice the original question was about Android and not forms. I will let the previous answer remain here in case anyone wanted to know about Forms solution.
So in Android the quivalant is ProgressDialog. I know you can use it like this:
ProgressDialog mDialog = new ProgressDialog(getApplicationContext());
mDialog.setMessage("Please wait...");
mDialog.setCancelable(false);
mDialog.show();
You put this code after starting you web call in another thread.
There might be better ways so search for the ProgressDialog and you will find them.
If you want to use ProgressDialog with MvvmCross (I see that tag under the topic) you may read an article by Stuart
Follow this sample layout skeleton for those screens where you need to show the activity indicator (Loader):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:id="#+id/parent_layout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/txt1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Text 1"
android:textSize="18dp"
android:textColor="#android:color/black"
android:paddingTop="20dp" />
<TextView
android:id="#+id/txt2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Text 2"
android:textSize="18dp"
android:textColor="#android:color/black"
android:paddingTop="20dp" />
</LinearLayout>
<FrameLayout
android:id="#+id/frame_layout"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerInParent="true"
android:background="#drawable/loader"
android:visibility="invisible">
<ProgressBar
android:id="#+id/progress_bar"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"/>
</FrameLayout>
</RelativeLayout>
Accordingly you need to control the FrameLayout from it's id containing the progress bar from your code end either in activity or if you are using fragment to make it visible during the service call and set the visibility to invisible once you received the response.

JavaFX Scene Builder 2.0 how to add an Image to a Label

I am using JavaFX Scene Builder 2.0 and I would like to add an image to a label using FXML.
In oracle docs, we can find how to achieve this using Java code, but I would like to achieve this using Scene Builder
There are two ways to achieve this
Using FXML
Using CSS
FXML
<Label text="My Image">
<graphic>
<ImageView fitWidth="150" preserveRatio="true" smooth="true">
<image>
<Image url="myImage.png"/>
</image>
</ImageView>
</graphic>
</Label>
Inside Scene Builder, drag an ImageView on top of a Label and it will automatically be set as a graphic for the label. Then select the ImageView and type the url of the image into the ImageView's image field in the Scene Builder properties pane.
CSS
Assign an id to the Label in your FXML. You will also find an id as the property of the Label in Scene Builder
<Label text= "My Image" id = "labelwithimage"/>
Now you can either assign the css values directly in fxml(makes things clumsy) or create a new css file and define your attributes in it
Direct Assignment
<Label text= "My Image" id = "labelwithimage" style="-fx-graphic:url('myImage.png'); -fx-graphic-text-gap : 10;"/>
For defining it in a css file, you need to create a css file, define the atrributes against the id assigned to the Label and include it in the FXML
mycss.css
#labelwithimage {
-fx-graphic: url("myImage.png");
-fx-graphic-text-gap : 10;
}
As you might have already guessed, -fx-graphic does everything that we wrote inside <graphic></graphic>, there are few other attributes like -fx-graphic-text-gap. You can find all the tags that can be used on Label in the css reference guide for label
Now the last thing in css is loading the css in the fxml. For this you need to include the following tag inside you fxml
<stylesheets>
<URL value="#mycss.css" />
</stylesheets>
Just make sure to have the proper imports in the FXML
It is also possible to do it directly in the Scene Builder, without touching the FXML or CSS manually.
Just drag and drop an ImageView node onto your label. You can then set the path to the image on the added ImageView node.
Alternatively, you may just drag an image file from your file explorer (or equivalent) to the label in Scene Builder. Scene Builder will add the intermediate ImageView node automatically. You may then adjust the path to your needs (document-relative, classpath-relative, etc.).
Actually the method is the same as in Java code and the direct modifications of the FXML: just set an ImageView as being the 'graphic' node of the label.
This also works the same for buttons.

Resources