ToList in MainViewModel - xamarin.forms

In a ViewModel i load data from a FirebaseDatabase and showing it in a CollectionView.
public MainViewModel()
{
var collection = firebase
.Child("Foto/")
.AsObservable<Fotos>()
.Subscribe((dbevent) =>
{
if (dbevent.Object != null)
{
Foto.Add(dbevent.Object);
}
});
}
But i want to change it ToList so i make it Descending based on BalId in the Database.
Want to use GetAllFotosDesending() but i cannot make it work in the MainViewModel.
public async Task<List<Fotos>> GetAllFotosDesending()
{
return (await firebase
.Child("Foto/")
.OnceAsync<Fotos>()).Select(item => new Fotos
{
BalId = item.Object.BalId,
RollNo = item.Object.RollNo,
Foto = item.Object.Foto,
Titel = item.Object.Titel,
Fototekst = item.Object.Fototekst
}).OrderByDescending(x => x.BalId).ToList();
}
2 options , or make it ToList in the MainViewModel or add GetAllFotosDesending() work in the MainViewModel.
The last option is maybe better ? but i cannot make this working when adding to the MainViewModel
This is the CollectionView with ItemsSource="{Binding Foto}"
<CollectionView
x:Name="Dood"
ItemsSource="{Binding Foto}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="Auto, *"
RowDefinitions="Auto, Auto, Auto, 1"
ColumnSpacing="10"
RowSpacing="5"
Padding="0,10">
<Image Source="{Binding Pic}"
Margin="20,0,0,10"
HeightRequest="70"
WidthRequest="70"
HorizontalOptions="Center"
VerticalOptions="Center"
Grid.RowSpan="3"
Grid.Row="0"
Grid.Column="0">
<Image.Clip>
<EllipseGeometry
Center="35,35"
RadiusX="35"
RadiusY="35"/>
</Image.Clip>
</Image>
<Label Text="{Binding Titel}"
FontAttributes="Bold"
Grid.Column="1"
Grid.Row="0"/>
<Label Text="{Binding Email}"
Grid.Column="1"
Grid.Row="1"/>
<Label Text="{Binding RollNo}"
Grid.Column="1"
Grid.Row="2"/>
<BoxView Style="{StaticResource SeparatorLine}"
Grid.Column="0"
Grid.Row="3"
Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Binding like this
public MainPage()
{
InitializeComponent();
BindingContext = new MainViewModel();
}

OrderBy does not have Alphanumeric comparison by default, the default Orderby only compares Alphabets or Numbers not a combination of both to handle this you need to create your own Alphanumeric Comparator that does this for you (especially if these are string values)
You can use this basic comparator for both Ascending and Descending orders:
public class AlphanumComparator : IComparer<object>
{
private enum ChunkType { Alphanumeric, Numeric };
private bool InChunk(char ch, char otherCh)
{
ChunkType type = ChunkType.Alphanumeric;
if (char.IsDigit(otherCh))
{
type = ChunkType.Numeric;
}
return (type != ChunkType.Alphanumeric || !char.IsDigit(ch))
&& (type != ChunkType.Numeric || char.IsDigit(ch));
}
public int Compare(object x, object y)
{
string firstString = x as string;
string secondString = y as string;
if (string.IsNullOrWhiteSpace(firstString) || string.IsNullOrWhiteSpace(secondString))
{
return 0;
}
int firstMarker = 0, secondMarker = 0;
while ((firstMarker < firstString.Length) || (secondMarker < secondString.Length))
{
if (firstMarker >= firstString.Length)
{
return -1;
}
else if (secondMarker >= secondString.Length)
{
return 1;
}
char firstCh = firstString[firstMarker];
char secondCh = secondString[secondMarker];
StringBuilder thisChunk = new StringBuilder();
StringBuilder thatChunk = new StringBuilder();
while ((firstMarker < firstString.Length) && (thisChunk.Length == 0 || InChunk(firstCh, thisChunk[0])))
{
thisChunk.Append(firstCh);
firstMarker++;
if (firstMarker < firstString.Length)
{
firstCh = firstString[firstMarker];
}
}
while ((secondMarker < secondString.Length) && (thatChunk.Length == 0 || InChunk(secondCh, thatChunk[0])))
{
thatChunk.Append(secondCh);
secondMarker++;
if (secondMarker < secondString.Length)
{
secondCh = secondString[secondMarker];
}
}
int result = 0;
// If both chunks contain numeric characters, sort them numerically
if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
{
int thisNumericChunk = Convert.ToInt32(thisChunk.ToString());
int thatNumericChunk = Convert.ToInt32(thatChunk.ToString());
if (thisNumericChunk < thatNumericChunk)
{
result = -1;
}
if (thisNumericChunk > thatNumericChunk)
{
result = 1;
}
}
else
{
result = thisChunk.ToString().CompareTo(thatChunk.ToString());
}
if (result != 0)
{
return result;
}
}
return 0;
}
}
Once you are done, you use it like below:
OrderByDescending(x => x.BalId, new AlphanumComparator());
OrderBy(x => x.BalId, new AlphanumComparator());

Solved like it this.
public async Task<List<Fotos>> GetAllFotosDesending()
{
return (await firebase
.Child("Foto/")
.OnceAsync<Fotos>()).Select(item => new Fotos
{
BalId = item.Object.BalId,
RollNo = item.Object.RollNo,
Foto = item.Object.Foto,
Titel = item.Object.Titel,
Fototekst = item.Object.Fototekst
}).OrderByDescending(x => x.BalId).ToList();
}
public async void InitializeAsync()
{
Fotos = await GetAllFotosDesending();
}
public MainViewModel()
{
InitializeAsync();
}

Related

ImageSource Binding not showing

I have already tried to solve it via reddit but i did not find any solution there. I have following code which gets me and ImageSource from my AccountViewModel and sets the ProfileImage property on the CommentViewModel to the same Image. The Image is not available as a saved files since it comes from my Backend Server. I already chacked, that the ProfileImage Property actually gets the right image, it does, also the Property Changed event fires and if i set the Property to an ImageSource.FromFile with a test Image which i have saved as a file it works. I really don't see any reason why it would not work with the image i get from the other viewmodel.
As the Image is a normal Property mit [BindableProperty] Annotation in the AccountViewModel and i have confirmed that the Types are exactly the same i do not show the AccoutnViewModel here to make it a bit shorter.
I do not get why the Start of every CodeBlock looks so strange.
CommentView:
<ContentPage.Content>
<StackLayout Margin="15">
<StackLayout Orientation="Horizontal">
<ffimageloading:CachedImage Source="{Binding ProfileImage, FallbackValue=default_user.jpg}"
HeightRequest="50"
WidthRequest="50"
VerticalOptions="CenterAndExpand"
HorizontalOptions="StartAndExpand">
<ffimageloading:CachedImage.Transformations>
<fftransformations:CircleTransformation/>
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
<Label Text="{Binding Username}"
FontSize="13"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>
CommentViewModel:
public partial class CommentViewModel : BaseViewModel
{
// == constants ==
// == observable properties ==
[ObservableProperty]
public long id;
[ObservableProperty]
public string username;
[ObservableProperty]
public string description;
[ObservableProperty]
ImageSource profileImage;
partial void OnProfileImageChanged(ImageSource value)
{
Console.WriteLine("profile changed");
}
// == constructors ==
public CommentViewModel(DisplayPostViewModel displayPostViewModel)
{
//profileImage = ImageSource.FromFile("default_user.jpg");
navigationService.DataBetweenViewModel<AccountViewModel>(this, "ProfileImage", "ProfileImage", true);
//profileImage = ImageSource.FromFile("default_user.jpg");
}
public CommentViewModel()
{
}
}
NavigationService:
public bool DataBetweenViewModel<ReceivingViewModel>(BaseViewModel sendingViewModel, string sendingPropertyName = null, string receivingPropertyName = null, bool isGettingFromOther = false)
where ReceivingViewModel : BaseViewModel
{
try
{
PropertyTransferObject transferObject;
var mainpage = Application.Current.MainPage as NavigationPage;
var tabbedPage = mainpage.RootPage as TabbedPage;
var recievingVM = tabbedPage.Children.SelectMany(tab => tab.Navigation.NavigationStack?
.Select(page => page.BindingContext)).OfType<ReceivingViewModel>();
if (isGettingFromOther)
{
transferObject = new PropertyTransferObject(recievingVM.First(), sendingViewModel, sendingPropertyName, receivingPropertyName);
}
else
{
transferObject = new PropertyTransferObject(sendingViewModel, recievingVM.First(), sendingPropertyName, receivingPropertyName);
}
objectMapper.TransferProperties(transferObject);
return true;
}
catch( Exception ex)
{
string e = ex.ToString();
return false;
}
}
ObjectMapper:
public void TransferProperties(PropertyTransferObject propertyTransferObject)
{
if (propertyTransferObject.SendingPropertyName != null && propertyTransferObject.ReceivingPropertyName != null
|| (propertyTransferObject.SendingPropertyName != String.Empty && propertyTransferObject.ReceivingPropertyName != String.Empty))
{
foreach (PropertyInfo recievingProp in propertyTransferObject.ReceivingObject.GetType().GetProperties())
{
foreach (PropertyInfo sendingProp in propertyTransferObject.SendingObject.GetType().GetProperties())
{
if (sendingProp.Name == propertyTransferObject.SendingPropertyName && recievingProp.Name == propertyTransferObject.ReceivingPropertyName)
{
recievingProp.SetValue(propertyTransferObject.ReceivingObject, sendingProp.GetValue(propertyTransferObject.SendingObject, null), null);
}
}
}
}
if (propertyTransferObject.SendingPropertyName == null && propertyTransferObject.ReceivingPropertyName == null
|| (propertyTransferObject.SendingPropertyName == String.Empty && propertyTransferObject.ReceivingPropertyName == String.Empty))
{
foreach (PropertyInfo recievingProp in propertyTransferObject.ReceivingObject.GetType().GetProperties())
{
foreach (PropertyInfo sendingProp in propertyTransferObject.SendingObject.GetType().GetProperties())
{
if (recievingProp.Name == sendingProp.Name && recievingProp.PropertyType == sendingProp.PropertyType)
{
recievingProp.SetValue(propertyTransferObject.ReceivingObject, sendingProp.GetValue(propertyTransferObject.SendingObject, null), null);
}
}
}
}
}

"MultiSelection" not working properly when using "Server Side Filtering" MudBlazor MudTable in Blazor WebAssembly

I started using MudBlazor in a Blazor WebAssembly project.
The problem is that when I use server side filtering and pagination in MudTable, MultiSelection not working properly. I can select all the rows by clicking "Select All" checkbox but selectAll checkbox remains unchecked when All are selected; and unable to unselect all again.
Unselect only working 1 by 1.
I am using this link:
https://try.mudblazor.com/snippet/mEQcYHEKpSAoCWSn
I appreciate your helps.
If you change the code like this it works.
<MudTable ServerData="#(new Func<TableState, Task<TableData<Element>>>(ServerReload))"
#ref="table"
CustomHeader="true"
#bind-SelectedItems="selectedItems1"
MultiSelection="true"
RowClassFunc="#SelectedRowClassFunc"
OnRowClick="RowClickEvent"
RowsPerPageChanged="OnRowsPerPageChanged"
T="Element">
<ToolBarContent>
<MudText Typo="Typo.h6">Periodic Elements</MudText>
<MudSpacer />
<MudTextField T="string" ValueChanged="#(s=>OnSearch(s))" Placeholder="Search" Adornment="Adornment.Start"
AdornmentIcon="#Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
</ToolBarContent>
<HeaderContent>
<MudTHeadRow IgnoreCheckbox="true">
<MudTh>
<MudCheckBox T="bool" Checked="IsSelectAllChecked" CheckedChanged="#Select"></MudCheckBox>
</MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Number)">Nr</MudTableSortLabel></MudTh>
<MudTh>Sign</MudTh>
<MudTh><MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<Element, object>(x=>x.Name)">Name</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Position)">Position</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Molar)">Mass</MudTableSortLabel></MudTh>
</MudTHeadRow>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Nr">#context.Number</MudTd>
<MudTd DataLabel="Sign">#context.Sign</MudTd>
<MudTd DataLabel="Name">#context.Name</MudTd>
<MudTd DataLabel="Position">#context.Position</MudTd>
<MudTd DataLabel="Molar mass">#context.Molar</MudTd>
</RowTemplate>
<NoRecordsContent>
<MudText>No matching records found</MudText>
</NoRecordsContent>
<LoadingContent>
<MudText>Loading...</MudText>
</LoadingContent>
<PagerContent>
<MudTablePager PageSizeOptions="new int[]{1, 5, 10}" />
</PagerContent>
<FooterContent>
<MudTd colspan="5">Select All</MudTd>
</FooterContent>
</MudTable>
<MudText >#($"{selectedItems1.Count} items selected")</MudText>
<MudText Inline="true">Selected items: #(selectedItems1==null ? "" : string.Join(", ", selectedItems1.OrderBy(x=>x.Sign).Select(x=>x.Sign)))</MudText>
#code {
private IEnumerable<Element> pagedData;
private MudTable<Element> table;
private int totalItems;
private string searchString = null;
private List<string> clickedEvents = new();
private HashSet<Element> selectedItems1 = new HashSet<Element>();
private async Task<TableData<Element>> ServerReload(TableState state)
{
IEnumerable<Element> data = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
await Task.Delay(300);
data = data.Where(element =>
{
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (element.Sign.Contains(searchString, StringComparison.OrdinalIgnoreCase))
return true;
if (element.Name.Contains(searchString, StringComparison.OrdinalIgnoreCase))
return true;
if ($"{element.Number} {element.Position} {element.Molar}".Contains(searchString))
return true;
return false;
}).ToArray();
totalItems = data.Count();
switch (state.SortLabel)
{
case "nr_field":
data = data.OrderByDirection(state.SortDirection, o => o.Number);
break;
case "sign_field":
data = data.OrderByDirection(state.SortDirection, o => o.Sign);
break;
case "name_field":
data = data.OrderByDirection(state.SortDirection, o => o.Name);
break;
case "position_field":
data = data.OrderByDirection(state.SortDirection, o => o.Position);
break;
case "mass_field":
data = data.OrderByDirection(state.SortDirection, o => o.Molar);
break;
}
pagedData = data.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArray();
return new TableData<Element>() {TotalItems = totalItems, Items = pagedData};
}
private void OnRowsPerPageChanged(int pageSize)
{
selectedItems1.Clear();
}
private void OnSelectedItemsChanged(HashSet<Element> elements)
{
clickedEvents.Add("Selected items changed");
}
private void OnSearch(string text)
{
searchString = text;
table.ReloadServerData();
}
private void RowClickEvent(TableRowClickEventArgs<Element> tableRowClickEventArgs)
{
clickedEvents.Add("Row has been clicked");
}
private string SelectedRowClassFunc(Element element, int rowNumber)
{
return selectedItems1.Contains(element) ? "selected" : string.Empty;
}
private bool IsSelectAllChecked
{
get
{
var currentPage = table.CurrentPage;
var rowsPerPage =table.RowsPerPage;
var currentPageItems = table.FilteredItems.Skip(currentPage * rowsPerPage).Take(rowsPerPage);
if (!selectedItems1.Any(x => currentPageItems.Any(y => x == y)))
{
return false;
}
else
{
return true;
}
}
}
private void Select()
{
var currentPage = table.CurrentPage;
var rowsPerPage = table.RowsPerPage;
var currentPageItems = table.FilteredItems.Skip(currentPage * rowsPerPage).Take(rowsPerPage);
if (!selectedItems1.Any(x => currentPageItems.Any(y => x == y)))
{
foreach(var item in currentPageItems)
{
selectedItems1.Add(item);
}
}
else
{
foreach(var item in currentPageItems)
{
selectedItems1.Remove(item);
}
}
}
}

PropertyChange of sub-ViewModel does not update UI in Xamarin

I have a page with a Telerik TabView. This contains two tabs. Each tab contains a view specified as ContentView in separate files. Each view has its own ViewModel, which are referenced in the ViewModel of the page.
In UI I use the sub-ViewModels as BindingContext for elements in the TabHeaders. On initial load the value of the used property is loaded correctly, but when the value is updated the UI doesn't update. Why?
All ViewModels are implementing the same base class which implements the INotifyPropertyChanged and the OnPropertyChanged() method for the used property is called and can be received in the own ViewModel.
Page-ViewModel:
public EquipmentPageViewModel(...){
var locator = (ViewModelLocator)Application.Current.Resources[nameof(ViewModelLocator)];
EquipmentOverviewViewModel = locator.GetViewModel(nameof(IEquipmentOverviewViewModel)) as IEquipmentOverviewViewModel;
CalibrationViewModel = locator.GetViewModel(nameof(ICalibrationViewModel)) as ICalibrationViewModel;
}
public IEquipmentOverviewViewModel EquipmentOverviewViewModel { get; private set; }
public ICalibrationViewModel CalibrationViewModel { get; private set; }
sub-ViewModel (EquipmentOverviewViewModel):
// property bound to an tabHeader in the page
public bool IsEquipmentValid
{
get
{
if (OrderWorkflow != null && OrderWorkflow.IsBatchEditing)
{
if (Operation == null || Operation.Equipment == null)
{
return false;
}
return IsQualityControlValid;
}
else
{
return Operation != null && Operation.Equipment != null && Operation.Equipment.IsEquipmentValid && IsQualityControlValid;
}
}
}
// property bound to an entry element in the view contained in the tab item
public string EquipmentNumber
{
get
{
return Equipment.EquipmentNumber;
}
set
{
if (value != Equipment.EquipmentNumber)
{
Equipment.EquipmentNumber = value;
OnPropertyChanged(nameof(EquipmentNumber));
OnPropertyChanged(nameof(IsEquipmentValid));
}
}
}
Page XAML (sub-ViewModel used in circle:CircleImage):
<ControlTemplate x:Key="EquipmentHeaderTemplate">
<Grid BackgroundColor="Transparent">
<BoxView IsVisible="{TemplateBinding IsSelected}"
BackgroundColor="#007bff"
VerticalOptions="End"
Margin="0, 5, 0, 0"
HeightRequest="3"/>
<StackLayout Orientation="Horizontal"
Margin="15"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand">
<!-- Validation mark -->
problem here---> <circle:CircleImage BindingContext="{Binding EquipmentOverviewViewModel}"
WidthRequest="10"
HeightRequest="10"
BorderColor="Transparent"
BorderThickness="1"
FillColor="#FF3B30"
Aspect="Fill"
IsVisible="{Binding IsEquipmentValid, Converter={StaticResource BooleanInverterConverter}, Mode=TwoWay}"
Margin="5, 5, 5, 0"
HorizontalOptions="Center"
VerticalOptions="Center" />
<iconize:IconLabel Text="ion-ios-construct"
TextColor="#007bff"
VerticalOptions="CenterAndExpand"/>
<Label Text="{Binding [OrderOperationDetailsPage_PivotItemEquipmentHeader], Source={StaticResource LocalizedString}}"
TextColor="#007bff"
Margin="10, 0, 0, 0"
VerticalOptions="CenterAndExpand"/>
</StackLayout>
</Grid>
</ControlTemplate>
...
<primitives:TabViewItem.Header>
<primitives:TabViewHeaderItem ControlTemplate="{StaticResource EquipmentHeaderTemplate}"
IsVisible="{Binding IsCalibrationAllowed}"/>
</primitives:TabViewItem.Header>
<primitives:TabViewItem.Content>
<equipment:EquipmentView></equipment:EquipmentView>
</primitives:TabViewItem.Content>
It seems that you didn't implement the Set method of IsEquipmentValid . So even if you change the value in other lines , it will never been changed .
public bool IsEquipmentValid
{
get
{
if (OrderWorkflow != null && OrderWorkflow.IsBatchEditing)
{
if (Operation == null || Operation.Equipment == null)
{
return false;
}
return IsQualityControlValid;
}
else
{
return Operation != null && Operation.Equipment != null && Operation.Equipment.IsEquipmentValid && IsQualityControlValid;
}
}
set
{
if (value != IsQualityControlValid)
{
value = IsQualityControlValid;
OnPropertyChanged(nameof(IsEquipmentValid));
}
}
}

Get data from Database using Controller xamarin Forms (MVC)

I need a help..
I need to get data from database using Controller.. But nothing happens when I do it.
My api is php codeigniter and i'm using X-API-Key.. I want to use It in MVC structure, because I need my view be navigable.
HttpClient
public class HttpClient
{
private Dictionary<string, string> _headers;
private HttpClient restClient;
public HttpClient(Dictionary<string, string> headers)
{
if (headers != null) _headers = headers;
else _headers = new Dictionary<string, string>();
}
public string this[string Key]
{
get
{
return _headers[Key];
}
set
{
_headers[Key] = value;
}
}
///<Summary>
/// HTTP GET REQUEST
///</Summary>
public async Task<HttpResponse<T>> ExcecuteAsync<T>(Method method, string baseUrl, Dictionary<string, object> formdata = null)
{
var client = new RestClient(baseUrl);
var request = new RestRequest(method);
foreach(var header in _headers)
{
request.AddHeader(header.Key, header.Value);
}
if(formdata != null)
{
foreach(var item in formdata)
{
request.AddParameter(item.Key, item.Value);
}
}
IRestResponse response = null;
Exception ex = null;
try
{
response = await client.ExecuteTaskAsync(request);
}
catch(Exception _ex)
{
ex = _ex;
}
var httpresponse = new HttpResponse<T>
{
Response = response
};
if (response == null)
{
httpresponse.Status = new StatusResponse
{
code = -1,
message = $"Nao se pode obter resposta do servidor, stacktrace:{ex.StackTrace}"
};
return httpresponse;
}
var jsonresult = response.Content;
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var telement = JsonConvert.DeserializeObject<T>(jsonresult);
httpresponse.Result = telement;
}else if(response.StatusCode == 0)
{
httpresponse.Status = new StatusResponse
{
code = 0,
message = $"Nao se pode obter resposta do servidor"
};
}
else
{
var telement = JsonConvert.DeserializeObject<StatusResponse>(jsonresult);
httpresponse.Status = telement;
}
return httpresponse; //null
}
This is my App.xaml - where i have my x-api-key
App.RestClient = new HttpClient(new Dictionary<string, string>
{
{"X-API-Key", "926ff4c0-d86e-421f-9192-82ac52650f5c" }
});
App.BaseUrl = "http://10.156.96.80/apiuthomi";
protected override async void OnStart()
{
var ListasHospitais = await new HospitalService(App.RestClient).all();
MainPage = new ListHospital(ListasHospitais);
}
This is ListHospital.xaml
<StackLayout>
<ListView
HasUnevenRows="True"
SeparatorVisibility="Default"
x:Name="ListasHospitais"
IsPullToRefreshEnabled="True"
Margin="10">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10" RowSpacing="10" ColumnSpacing="10" BackgroundColor="White" Margin="0 , 0 , 0, 10">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="1"
VerticalOptions="End"
Text="{Binding Nome}"
MaxLines="1"
LineBreakMode="TailTruncation"
FontAttributes="Bold"
/>
<Label Grid.Column="1"
Grid.Row="1"
Text="{Binding Detalhes}"
VerticalOptions="Start"
LineBreakMode="TailTruncation"
MaxLines="2"
/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
This is my ListHospital.xaml.cs
public partial class ListHospital : ContentPage
{
public ObservableCollection<Cliente> _clientes;
public ListHospital(List<Cliente>clientes)
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
_clientes = new ObservableCollection<Cliente>();
ListasHospitais.ItemsSource = _clientes;
foreach(var cliente in clientes)
{
_clientes.Add(cliente);
}
}
public void voltar_Click(object sender, System.EventArgs e)
{
Navigation.PopAsync();
}
}
HospitalService = where i will write all methods
public class HospitalService
{
private HttpClient _restclient;
public HospitalService(HttpClient restclient)
{
if (restclient != null) _restclient = restclient;
else throw new NullReferenceException("http nao pode ser nulo");
}
public async Task<List<Cliente>>all()
{
var response = await _restclient.GetAsync<List<Cliente>>("http://10.156.96.80/apiuthomi/cliente/all");
if (response.Result != null) return response.Result;
return new List<Cliente>();
}
}
until here everything is going well and it's working.. but the problem is that my view listHospital os no longer clickable.. like I want tho make this page be navigable...
this public ListHospital(List<Cliente>clientes)does not allow the clicked method to be valid in my view
I can't do await Navigation.PushAsync(new ListHospital()) , It give
me an error
this is because your ListHosptial page does not have a default (empty) constructor and you are not passing the required data. You can fix this by adding an default constructor
public ListHospital()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
...
}
if you do this then ListHospital needs to load it's own data. The easiest way to do this is probably to add a call to your services in the OnAppearing method
public override async void OnAppearing()
{
// call services to load data and assign ItemsSource
var data = await new HospitalService(App.RestClient).all();
ListasHospitais.ItemsSource = data;
}

Xamarin Forms MVVM (Prism) with Media.Plugin - How to get a taken picture from device Camera

How to take a picture by the camera and show in display before saving data.....
on Page..
<Image Source="{Binding ImageTakeFile2.source}" Grid.Column="0" WidthRequest="100" HeightRequest="100" HorizontalOptions="Start"/>
In the ViewModel..
private MediaFile _photo;
_photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{ Directory = "Sample", Name = "test.jpg", PhotoSize = PhotoSize.MaxWidthHeight, MaxWidthHeight = imageSize });
ImageTakeFile2.Source = ImageSource.FromStream(() =>
{
var stream = _photo.GetStream();
return stream;
});
Use:
ImageTakeFile2.Source = ImageSource.FromFile(_photo.Path);
.Source must be declared as ImageSource
Solved!...
<Image Source="{Binding Img}"/>
In ViewModel...
public ImageSource Img
{
get { return _img; }
set { _img = value;
OnPropertyChanged("Img");
}
}
private MediaFile _photo; { get; set; }
Img = ImageSource.FromFile(_photo.Path);

Resources