I am new to Xamarin Forms and I am making an application on a system to manage automotive vehicle maintenance services. So far I can save, modify and show data, when I save new vehicles my view shows them to me and updates to show the vehicle, but when I want to edit the vehicles, I can edit them and the changes are shown in Firebase, but my view is still the same same until I close and open the application again, how can I make these changes visible? Any help will be heartily appreciated
My view
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CMP.Vistas.Vehiculos"
NavigationPage.HasNavigationBar="False"
BackgroundColor="White"
Visual="Material">
<StackLayout>
<Frame BackgroundColor="#D48593"
HorizontalOptions="FillAndExpand"
HeightRequest="64"
Margin="0"
Padding="0"
HasShadow="False"
CornerRadius="0">
<Label Text="CalMaP"
HorizontalOptions="End"
VerticalOptions="Center"
FontSize="23"
FontAttributes="Bold"
Margin="0,0,40,0"
TextColor="White" />
</Frame>
<Grid RowDefinitions="*">
<RefreshView RefreshColor="#D48593"
Refreshing="RefreshView_Refreshing"
x:Name="RefreshCar">
<ScrollView>
<StackLayout x:Name="ContainerVehiculos"
VerticalOptions="Start"
Margin="10,12,10,0"
Orientation="Vertical"
Spacing="20">
</StackLayout>
</ScrollView>
</RefreshView>
<ImageButton Source="Iconpause.png"
VerticalOptions="EndAndExpand"
HorizontalOptions="EndAndExpand"
HeightRequest="60"
WidthRequest="60"
Margin="0,0,30,30"
CornerRadius="100"
BackgroundColor="White"
Command="{Binding NavAddVehiculoCommand}" />
</Grid>
</StackLayout>
</ContentPage>
my View C#
using CMP.VistaModelo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace CMP.Vistas
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Vehiculos : ContentPage
{
VMVehiculos vm;
public Vehiculos()
{
InitializeComponent();
vm = new VMVehiculos(Navigation, ContainerVehiculos);
BindingContext = vm;
Appearing += Vehiculos_Appearing;
}
private async void Vehiculos_Appearing(object sender, EventArgs e)
{
await vm.Mostrarvehiculos(ContainerVehiculos);
}
}
}
my viewModel:
using CMP.Datos;
using CMP.Modelo;
using CMP.Servicios;
using CMP.VistaModelo.Formularios;
using CMP.Vistas;
using CMP.Vistas.Formularios;
using Firebase.Database.Query;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace CMP.VistaModelo
{
public class VMVehiculos : BaseViewModel
{
#region VARIABLES
Dvehiculos funcion = new Dvehiculos();
List<MVehiculos> _ListaVehiculos;
private ObservableCollection<MVehiculos> _MVehiculos;
#endregion
#region CONSTRUCTOR
public VMVehiculos(INavigation navigation, StackLayout Contenedor)
{
Navigation = navigation;
Mostrarvehiculos(Contenedor);
}
public VMVehiculos()
{
}
#endregion
#region OBJETOS
public List<MVehiculos> ListaVehiculos
{
get { return _ListaVehiculos; }
set { SetValue(ref _ListaVehiculos, value); }
}
#endregion
#region PROCESOS
public void DibujarVehiculos(MVehiculos Item, StackLayout Contenedor)
{
var carril = Contenedor;
var frame = new Frame
{
CornerRadius = 15,
BackgroundColor = Color.FromRgb(240, 220, 230),
BorderColor = Color.FromHex("#EEEDED"),
HasShadow = false,
};
var grid = new Grid
{
ColumnDefinitions = new ColumnDefinitionCollection
{
new ColumnDefinition{ Width = new GridLength(50) },
new ColumnDefinition{ Width = new GridLength(150) },
new ColumnDefinition{ Width = new GridLength(83) },
},
HorizontalOptions = LayoutOptions.FillAndExpand,
};
var image = new Image
{
Source = Item.Icono,
HeightRequest = 50,
WidthRequest = 50,
Margin = new Thickness(0, 0, 6, 0),
HorizontalOptions = LayoutOptions.Start,
};
Grid.SetRowSpan(image, 2);
Grid.SetColumn(image, 0);
var labelNombre = new Label
{
Text = Item.Nombre,
HorizontalOptions = LayoutOptions.StartAndExpand,
VerticalOptions = LayoutOptions.Center,
FontAttributes = FontAttributes.Bold,
};
Grid.SetRowSpan(labelNombre, 2);
Grid.SetColumn(labelNombre, 1);
var labelKilometraje = new Label
{
Text = Item.Kilomtraje.ToString(),
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center,
FontSize = 15,
};
Grid.SetRow(labelKilometraje, 0);
Grid.SetColumn(labelKilometraje, 2);
var labelEstado = new Label
{
Text = Item.Estado,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center,
FontSize = 15,
TextColor = Color.FromHex(_Color(Item.Estado))
};
Grid.SetRow(labelEstado, 1);
Grid.SetColumn(labelEstado, 2);
grid.Children.Add(image);
grid.Children.Add(labelNombre);
grid.Children.Add(labelKilometraje);
grid.Children.Add(labelEstado);
frame.Content = grid;
var tap = new TapGestureRecognizer();
tap.Tapped += async (Object sender, EventArgs e) =>
{
await Navigation.PushAsync(new DataVehiculo(Item));
};
grid.GestureRecognizers.Add(tap);
carril.Children.Add(frame);
}
public string _Color(string parametro)
{
string color = "";
if (parametro.Equals("En uso"))
{
color = "#9A8200";
}
else if (parametro.Equals("Disponible"))
{
color = "#35B121";
}
else if (parametro.Equals("En servicio"))
{
color = "#CA1D27";
}
return color;
}
public async Task Mostrarvehiculos(StackLayout Contenedor)
{
funcion = new Dvehiculos();
ListaVehiculos = await funcion.ObtenerVehiculos();
foreach (var item in ListaVehiculos)
{
DibujarVehiculos(item, Contenedor);
}
}
public async Task IraAddVehiculo()
{
await Navigation.PushAsync(new AddVehiculo());
}
#endregion
#region COMANDOS
public ICommand NavAddVehiculoCommand => new Command(async () => await IraAddVehiculo());
#endregion
}
}
My Firebase data:
using CMP.Modelo;
using CMP.Servicios;
using Firebase.Database;
using Firebase.Database.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Essentials;
namespace CMP.Datos
{
public class ConexionFirebase
{
public static FirebaseClient FBCliente = new FirebaseClient("https://cmpsoft-260301-default-rtdb.firebaseio.com/");
}
internal class Dvehiculos
{
public async Task<List<MVehiculos>> ObtenerVehiculos()
{
return (await ConexionFirebase.FBCliente
.Child("Servicios")
.Child("Vehiculos")
.OnceAsync<MVehiculos>()).Select(Item => new MVehiculos
{
IdVehiculo = Item.Key,
NumeroEconomico = Item.Object.NumeroEconomico,
Modelo = Item.Object.Modelo,
Nombre = Item.Object.Nombre,
Tipo = Item.Object.Tipo,
NumeroDeSerie = Item.Object.NumeroDeSerie,
Icono = Item.Object.Tipo == "pesado" ? "BttnTruck.png" : "BttnCar.png",
Kilomtraje = Item.Object.Kilomtraje,
HoraDeUso = Item.Object.HoraDeUso,
CantLlantas = Item.Object.CantLlantas,
TiempoVidaLlantas = Item.Object.TiempoVidaLlantas,
DatosExtras = Item.Object.DatosExtras,
Observaciones = Item.Object.Observaciones,
Estado = Item.Object.Estado,
}).ToList();
}
public async Task InsertarVehiculo(MVehiculos parametro)
{
await ConexionFirebase.FBCliente
.Child("Servicios")
.Child("Vehiculos")
.PostAsync(new MVehiculos()
{
IdVehiculo = parametro.IdVehiculo,
NumeroEconomico = parametro.NumeroEconomico,
Modelo = parametro.Modelo,
Nombre = parametro.Nombre,
Tipo = parametro.Tipo,
NumeroDeSerie = parametro.NumeroDeSerie,
Kilomtraje = parametro.Kilomtraje,
HoraDeUso = parametro.HoraDeUso,
CantLlantas = parametro.CantLlantas,
TiempoVidaLlantas = parametro.TiempoVidaLlantas,
DatosExtras = parametro.DatosExtras,
Observaciones = parametro.Observaciones,
Estado = parametro.Estado
});
}
public async Task<List<MVehiculos>> MostrarVehiculosxIdVehiculo(string IdVehiculo)
{
return (await ConexionFirebase.FBCliente
.Child("Servicios")
.Child("Vehiculos")
.OnceAsync<MVehiculos>())
.Where(a => a.Object.IdVehiculo == IdVehiculo).Select(Item => new MVehiculos
{
NumeroEconomico = Item.Object.NumeroEconomico
}).ToList();
}
public async Task<List<MVehiculos>> ObtenerVehiculoxId(string IdVehiculo)
{
return (await ConexionFirebase.FBCliente
.Child("Servicios")
.Child("Vehiculos")
.OnceAsync<MVehiculos>())
.Where(a => a.Object.IdVehiculo == IdVehiculo).Select(Item => new MVehiculos
{
IdVehiculo = Item.Key,
NumeroEconomico = Item.Object.NumeroEconomico,
Modelo = Item.Object.Modelo,
Nombre = Item.Object.Nombre,
Tipo = Item.Object.Tipo,
NumeroDeSerie = Item.Object.NumeroDeSerie,
Icono = Item.Object.Tipo == "pesado" ? "BttnTruck.png" : "BttnCar.png",
Kilomtraje = Item.Object.Kilomtraje,
HoraDeUso = Item.Object.HoraDeUso,
CantLlantas = Item.Object.CantLlantas,
TiempoVidaLlantas = Item.Object.TiempoVidaLlantas,
DatosExtras = Item.Object.DatosExtras,
Observaciones = Item.Object.Observaciones,
Estado = Item.Object.Estado,
}).ToList();
}
public async Task EditarVehiculo(MVehiculos parametro)
{
var data = (await ConexionFirebase.FBCliente
.Child("Servicios")
.Child("Vehiculos")
.OnceAsync<MVehiculos>())
.Where(a => a.Object.IdVehiculo == parametro.IdVehiculo)
.FirstOrDefault();
await ConexionFirebase.FBCliente
.Child("Servicios")
.Child("Vehiculos")
.Child(data.Key)
.PutAsync(new MVehiculos()
{
IdVehiculo = parametro.IdVehiculo,
NumeroEconomico = parametro.NumeroEconomico,
Modelo = parametro.Modelo,
Nombre = parametro.Nombre,
Tipo = parametro.Tipo,
NumeroDeSerie = parametro.NumeroDeSerie,
Kilomtraje = parametro.Kilomtraje,
HoraDeUso = parametro.HoraDeUso,
CantLlantas = parametro.CantLlantas,
TiempoVidaLlantas = parametro.TiempoVidaLlantas,
DatosExtras = parametro.DatosExtras,
Observaciones = parametro.Observaciones,
Estado = parametro.Estado
});
}
}
}
My Model:
using System;
using System.Collections.Generic;
using System.Text;
namespace CMP.Modelo
{
public class MVehiculos
{
public string IdVehiculo { get; set; }
public string NumeroEconomico { get; set; }
public string Modelo { get; set; }
public string Nombre { get; set; }
public string Tipo { get; set; }
public string NumeroDeSerie { get; set; }
public string Icono { get; set; }
public int Kilomtraje { get; set; }
public int HoraDeUso { get; set; }
public int CantLlantas { get; set; }
public int TiempoVidaLlantas { get; set; }
public string DatosExtras { get; set; }
public string Observaciones { get; set; }
public string Estado { get; set; }
}
}
So far I have tried changing the Firebase code, also the views and changing the code of my viewmodel, but I can't think of what else to do.
As Jason said that MVehiculos
needs to implement INotifyPropertyChanged
or otherwise be made Observable
:
public partial class MVehiculos : ObservableObject
{
[ObservableProperty]
public string idVehiculo;
[ObservableProperty]
public string numeroEconomico;
[ObservableProperty]
public string modelo;
[ObservableProperty]
public string nombre;
[ObservableProperty]
public string tipo;
[ObservableProperty]
public string numeroDeSerie;
[ObservableProperty]
public string icono;
[ObservableProperty]
public int kilomtraje;
[ObservableProperty]
public int horaDeUso;
[ObservableProperty]
public int cantLlantas;
[ObservableProperty]
public int tiempoVidaLlantas;
[ObservableProperty]
public string datosExtras;
[ObservableProperty]
public string observaciones;
[ObservableProperty]
public string estado;
}
And BaseViewModel
class also needs to inherit ObservableObject
.
For more info you can refer to the doc: ObservableProperty attribute.