Binding Class in MVVM Light to RelayCommand in Xamarin - android

I am trying to bind the following class to a relaycommand.
public class UserAuth
{
public string UserName { get; set; }
public string Password { get; set; }
}
This is my MainActivity Class:
public partial class MainActivity : ActivityBaseEx
{
private Binding<string, UserAuth> _userInformation;
private Binding<string, UserAuth> _cool;
public LoginViewModel LoginViewModel
{
get
{
return App.Locator.Login;
}
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
_userInformation = this.SetBinding(()=> **....... WHAT GOES HERE!! I can do this for a simple string, but cannot figure it out for a class!**
// Get our button from the layout resource and attach an event to it
var signInButton = FindViewById<Button>(Resource.Id.btnSingIn);
signInButton.SetCommand("Click", LoginViewModel.LoginCommand, _userInformation);
}
}
This is my RelayCommand in my View Model
public RelayCommand<UserAuth> LoginCommand
{
get
{
return _loginCommand ?? (_loginCommand = new RelayCommand<UserAuth>(
async (userAuth) =>
{
_isLoading = true;
try
{
// var loggedIn = await _loginService.AuthenticateUser("emediaqa1", "p098765");
var loggedIn = await _loginService.AuthenticateUser(userAuth.UserName, userAuth.Password);
_isLoading = false;
}
catch (Exception ex)
{
var dialog = ServiceLocator.Current.GetInstance<IDialogService>();
dialog.ShowError(ex, "Error Authenticating", "OK", null);
}
_isLoading = false;
}));
}
}
My problem is with this line:
_userInformation = this.SetBinding(()=> // WHAT GOES HERE!! I can do this for a simple
//string, but cannot figure it out for a class!
Please help!
Thanks!!

I use something like this in the MainActivity.OnCreate:
_usernameBinding = this.SetBinding(() => Vm.userAuth.Username, () => Username.Text, BindingMode.TwoWay);
_passwordBinding = this.SetBinding(() => Vm.userAuth.Password, () => Password.Text, BindingMode.TwoWay);
So you need 2 bindings, one for userName and one for Password.

Related

What did I do wrong? Mailcore2

I am trying connect React Native with Mailcore2. Use mailcore2-android-4.aar (already build): http://d.etpan.org/mailcore2-deps/mailcore2-android/
I create my class and connect it with React Native App, as a result I can use debug in Android Studio 2021.3.1 (Dolphin)
My code:
public class Mail extends ReactContextBaseJavaModule {
private ReactContext mReactContext;
private IMAPFetchMessagesOperation fetchMessagesOp;
private java.util.List\<IMAPMessage\> messages;
private IMAPSession session;
private String status = "Failed";
public interface Callbacks {}
public Mail(ReactApplicationContext reactContext) {
super(reactContext);
this.mReactContext = reactContext;
session = new IMAPSession();
session.setUsername("my-email");
session.setPassword("my-client-secret");
session.setHostname("imap.yandex.ru");
session.setPort(993);
session.setConnectionType(ConnectionType.ConnectionTypeTLS);
}
#Override
public String getName() {
return "Mail";
}
#ReactMethod
public void updateMessages(Callback cb) {
fetchMessagesOp = session.fetchMessagesByNumberOperation(
"INBOX",
IMAPMessagesRequestKind.IMAPMessagesRequestKindHeaders |
IMAPMessagesRequestKind.IMAPMessagesRequestKindStructure,
IndexSet.indexSetWithRange(new Range(1, Range.RangeMax))
);
fetchMessagesOp.start(new OperationCallback() {
#Override
public void succeeded() {
status = "OK";
messages = fetchMessagesOp.messages();
cb.invoke(null, "");
}
#Override
public void failed(MailException ex) {
cb.invoke(ex.toString(), null);
}
});
}
#ReactMethod
public void getStatus(Callback cb) {
try {
if (Objects.equals(status, "OK")) {
cb.invoke(null, "OK");
} else {
cb.invoke("Failed", null);
}
} catch (Exception ex) {
cb.invoke(ex.toString(), null);
}
}
#ReactMethod
public void getMessages(Callback cb) {
if (messages != null) {
String tempString = "";
for (int indexMsg = 0; indexMsg < messages.size(); ++indexMsg) {
tempString += messages.get(indexMsg).toString();
}
cb.invoke(null, tempString);
} else {
cb.invoke("No messages", null);
}
}
}
My code for calling this class from React Native App:
let status = false;
function checkStatus() {
console.log('checkStatus');
NativeModules.Mail.getStatus((err: any, s: string) =\> {
if (err !== null) {
console.log(s);
} else {
status = true;
}
});
if (status === false) setTimeout(checkStatus, 5000);
}
function getMessages() {
NativeModules.Mail.updateMessages((err: any, s: string) =\> {
if (err === null) {
console.log(s);
} else {
console.log(err);
}
});
When I clicked on the button with included getMessages(), App crashed

Xamarin.Forms Imagesource issue

I have a view with an image: <Image Source="{Binding MainUrl}"/>
Image binding value : My image source on loading from database
the value of MainUrl variable is stored in an sqlite table.public string LogoUrl { get; set; }
viewmodel :
private string _logoUrl;
public string LogoUrl
{
get { return _logoUrl; }
set
{
SetValue(ref _logoUrl, value);
OnPropertyChanged(nameof(LogoUrl));
}
}
the user has the option to change the image using filepicker :
var file = await FilePicker.PickAsync(options);
if (file == null)
{
return;
}
var stream = await file.OpenReadAsync();
MainUrl = ImageSource.FromStream(() => stream);
LblImportLogo = file.FullPath;
Parameter.LogoUrl = file.FullPath;
when I choose an image with filepicker, this one is well displayed and the the path is saved into sqlite table but when I restart the application, the image is no longer displayed despite the path being well informed (this one is external). the problem is in all platforms, UWP,android and IOS. can you help me find a solution.
Mainpage.xaml.cs :
public MainPage()
{
var parameterStore = new SQLiteParameterStore(DependencyService.Get<ISQLiteDb>());
var pageService = new PageService();
ViewModel = new MainPageViewModel(parameterStore, pageService);
InitializeComponent();
NavigationPage.SetHasBackButton(this, false);
NavigationPage.SetHasNavigationBar(this, false);
}
protected override void OnAppearing()
{
ViewModel.LoadDataCommand.Execute(null);
base.OnAppearing();
}
public MainPageViewModel ViewModel
{
get { return BindingContext as MainPageViewModel; }
set { BindingContext = value; }
}
MainPageViewModel :
......
private ImageSource _mainurl;
public ImageSource MainUrl
{
get { return _mainurl; }
set
{
SetValue(ref _mainurl, value);
OnPropertyChanged(nameof(MainUrl));
}
}
......
private async Task LoadData()
{
var parameters = await _parameterStore.GetAll();
var elts = parameters.Count();
if (elts < 1)
{
//set default values
mainParameter = new Parameter();
mainParameter.LogoUrl = "default.jpg";
MainUrl = mainParameter.LogoUrl;
}
else
{
//set parameters
mainParameter = parameters[0];
MainUrl = ImageSource.FromFile(mainParameter.LogoUrl);
}
}

Wrong Data Received from Firebase

I'm trying to get the data from Firebase, but when I debug my app I can see that the app has found the key I put, but I received no data on the value:
DatabaseReference taxiref = childRef.child(chapa);
taxiref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Sesion.taxis.add(dataSnapshot.getValue(Taxi.class));
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
As you can see in the following code, that my structure from Firebase:
"taxis" : {
"bbb222" : {
"año" : 1998,
"modelo" : "Gol",
"ubicaciones" : {
"u1" : {
"fecha" : "20-12-2016 12:30",
"latitud" : 31231231,
"longitud" : 2131241
},
"u2" : {
"fecha" : "20-12-2016 12:31",
"latitud" : 31231232,
"longitud" : 2131243
}
}
},
And as you can see on the following image when I debugged the code the key I got is correct, but I didn't receive any value, could somebody help me with that?
Here its the taxi.java class:
public class Taxi {
private String año;
private String modelo;
private String chapaTaxi;
private LinkedList<Ubicaciones> ubicaciones;
public void diagramarRecorrido() {
for (Ubicaciones u : getUbicaciones()) {
u.ubicarMapa();
}
}
public String getAño() {
return año;
}
public void setAño(String año) {
this.año = año;
}
public String getModelo() {
return modelo;
}
public void setModelo(String modelo) {
this.modelo = modelo;
}
public String getChapaTaxi() {
return chapaTaxi;
}
public void setChapaTaxi(String chapaTaxi) {
this.chapaTaxi = chapaTaxi;
}
public LinkedList<Ubicaciones> getUbicaciones() {
return ubicaciones;
}
public void setUbicaciones(LinkedList<Ubicaciones> ubicaciones) {
this.ubicaciones = ubicaciones;
}
}
Sorry guys my bad, childRef was a variable:
private static DatabaseReference childRef= ref.child("taxis");
and that was the problem as you can see the child its taxis but I had Taxis thats why I never got any results from the firebase, thanks to all for all your help.

NullReferenceException in MvvmCross Messenger

This is code in my ViewModel
public ICommand GoToCartCommand{
get{
return new MvxCommand (() => {
var cartViewModel = Mvx.Resolve<CartViewModel>();
if (cartViewModel != null)
{
cartViewModel.cartlist.Add(new CartItemViewModel() { Name = Name, ID = ID, UnitPrice = double.Parse(Price), Quantity = 1, Description = Description, Image = Image });
}
cartListCount = cartViewModel.cartlist.Count;
var messanger = Mvx.Resolve<IMvxMessenger>();
var message = new MyMessage(this,"Product has been added",cartListCount);
messanger.Publish(message);
});
}
}
public class MyMessage : MvxMessage
{
public int CartList_Count{ get; set;}
public string Message{ get; set;}
public MyMessage(object sender,string _message,int _cartlist_count) : base(sender) {
this.Message = _message;
this.CartList_Count = _cartlist_count;
}
}
This is code in my View :
var messenger = Mvx.Resolve<IMvxMessenger>();
_token = messenger.Subscribe<MyMessage>(OnInputIsNeeded,MvxReference.Strong);
private void OnInputIsNeeded(MyMessage _Message)
{
Toast.MakeText (this.Activity,_Message.Message, ToastLength.Short).Show();
}
My problem here is when I comeback to this view after going to next view OnInputisNeeded the method is called two times.
And when go back from this view and when I again come to this view and click button I get a NullReferenceException.
What is the solution?
What is the meaning of this:
Nothing registered for messages of type MvxSubscriberChangeMessage
How do i register MvxSubscriberChangeMessage?

Floating Action Button in Xamarin.Forms

I had completed my App's home page in Xamarin.Forms Portable.
Now i want to add a Flotation Action Button In my Android Project !
Is there any way to add FAB for Android in my existing home page, which was coded in Xamarin.Forms Portable.
OR
I want to create a separate home page for Android and add call it as a MainPage for android ?
Thanks and Regards.
Before the official support library came out I ported the FAB over.
There is now a Xamarin.Forms sample in my GitHub repo that you can use: https://github.com/jamesmontemagno/FloatingActionButton-for-Xamarin.Android
Build a Custom Control
For the FAB's properties to be bindable in Xamarin.Forms, we need a custom control with bindable properties.
public class FloatingActionButtonView : View
{
public static readonly BindableProperty ImageNameProperty = BindableProperty.Create<FloatingActionButtonView,string>( p => p.ImageName, string.Empty);
public string ImageName
{
get { return (string)GetValue (ImageNameProperty); }
set { SetValue (ImageNameProperty, value); }
}
public static readonly BindableProperty ColorNormalProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorNormal, Color.White);
public Color ColorNormal
{
get { return (Color)GetValue (ColorNormalProperty); }
set { SetValue (ColorNormalProperty, value); }
}
public static readonly BindableProperty ColorPressedProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorPressed, Color.White);
public Color ColorPressed
{
get { return (Color)GetValue (ColorPressedProperty); }
set { SetValue (ColorPressedProperty, value); }
}
public static readonly BindableProperty ColorRippleProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorRipple, Color.White);
public Color ColorRipple
{
get { return (Color)GetValue (ColorRippleProperty); }
set { SetValue (ColorRippleProperty, value); }
}
...
}
We will then map each property to a corresponding property on the native FAB control.
Attach a Renderer
If we want to use a native control in Xamarin.Forms, we need a renderer. For simplicity, lets use a ViewRenderer. This renderer will map our custom FloatingActionButtonView to an Android.Widget.FrameLayout.
public class FloatingActionButtonViewRenderer : ViewRenderer<FloatingActionButtonView, FrameLayout>
{
...
private readonly Android.Content.Context context;
private readonly FloatingActionButton fab;
public FloatingActionButtonViewRenderer()
{
context = Xamarin.Forms.Forms.Context;
fab = new FloatingActionButton(context);
...
}
protected override void OnElementChanged(ElementChangedEventArgs<FloatingActionButtonView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || this.Element == null)
return;
if (e.OldElement != null)
e.OldElement.PropertyChanged -= HandlePropertyChanged;
if (this.Element != null) {
//UpdateContent ();
this.Element.PropertyChanged += HandlePropertyChanged;
}
Element.Show = Show;
Element.Hide = Hide;
SetFabImage(Element.ImageName);
fab.ColorNormal = Element.ColorNormal.ToAndroid();
fab.ColorPressed = Element.ColorPressed.ToAndroid();
fab.ColorRipple = Element.ColorRipple.ToAndroid();
var frame = new FrameLayout(Forms.Context);
frame.RemoveAllViews();
frame.AddView(fab);
SetNativeControl (frame);
}
public void Show(bool animate = true)
{
fab.Show(animate);
}
public void Hide(bool animate = true)
{
fab.Hide(animate);
}
void HandlePropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "Content") {
Tracker.UpdateLayout ();
}
else if (e.PropertyName == FloatingActionButtonView.ColorNormalProperty.PropertyName)
{
fab.ColorNormal = Element.ColorNormal.ToAndroid();
}
else if (e.PropertyName == FloatingActionButtonView.ColorPressedProperty.PropertyName)
{
fab.ColorPressed = Element.ColorPressed.ToAndroid();
}
else if (e.PropertyName == FloatingActionButtonView.ColorRippleProperty.PropertyName)
{
fab.ColorRipple = Element.ColorRipple.ToAndroid();
}
...
}
void SetFabImage(string imageName)
{
if(!string.IsNullOrWhiteSpace(imageName))
{
try
{
var drawableNameWithoutExtension = Path.GetFileNameWithoutExtension(imageName);
var resources = context.Resources;
var imageResourceName = resources.GetIdentifier(drawableNameWithoutExtension, "drawable", context.PackageName);
fab.SetImageBitmap(Android.Graphics.BitmapFactory.DecodeResource(context.Resources, imageResourceName));
}
catch(Exception ex)
{
throw new FileNotFoundException("There was no Android Drawable by that name.", ex);
}
}
}
}
Pull it all Together
OK! We've built the custom control, and mapped it to a renderer. The last step is laying out the control in our view.
public class MainPage : ContentPage
{
public MainPage()
{
var fab = new FloatingActionButtonView() {
ImageName = "ic_add.png",
ColorNormal = Color.FromHex("ff3498db"),
ColorPressed = Color.Black,
ColorRipple = Color.FromHex("ff3498db")
};
// Main page layout
var pageLayout = new StackLayout {
Children =
{
new Label {
VerticalOptions = LayoutOptions.CenterAndExpand,
XAlign = TextAlignment.Center,
Text = "Welcome to Xamarin Forms!"
}
}};
var absolute = new AbsoluteLayout() {
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand };
// Position the pageLayout to fill the entire screen.
// Manage positioning of child elements on the page by editing the pageLayout.
AbsoluteLayout.SetLayoutFlags(pageLayout, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(pageLayout, new Rectangle(0f, 0f, 1f, 1f));
absolute.Children.Add(pageLayout);
// Overlay the FAB in the bottom-right corner
AbsoluteLayout.SetLayoutFlags(fab, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(fab, new Rectangle(1f, 1f, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
absolute.Children.Add(fab);
Content = absolute;
}
}
Complete code on Github : Floating Action Button Xamarin.Forms

Categories

Resources