Child Viewmodel in the tab page is not working in xamarin forms - xamarin

I have tabbed pages in my project where I have to bind same few items in all the three tabbed pages.But the viewmodel is not executing in that.
xaml :
<TabbedPage.Children>
<Views:TabPage1>
<Views:TabPage1.BindingContext>
<ViewModel:TabPage1VM/>
</Views:TabPage1.BindingContext>
</Views:TabPage1>
<Views:TabPage2>
<Views:TabPage2.BindingContext>
<ViewModel:TabPage2VM/>
</Views:TabPage2.BindingContext>
</Views:TabPage2>
<Views:TabPage3>
<Views:TabPage3.BindingContext>
<ViewModel:TabPage3VM/>
</Views:TabPage3.BindingContext>
</Views:TabPage3>
</TabbedPage.Children>
Now each Viewmodel is inheriting the main Viewmodel and in one child ViewModel :
RestClient temp = new RestClient();
var gettempdetails = temp.Servicetypes();
if (gettempdetails.status == "success")
{
listdetails = new List<ServiceDetail>();
foreach (Datum2 data in gettempdetails.service_details)
{
Datum3 Display = new Datum2();
Display.name = data.name;
Display.rate = data.rate;
Display.time = data.time;
Display.type = data.type;
Display.image = "uncheck.png";
}
While debugging, the above code is not executing.
Any Solution?
Also here is the code for RestClient inside the child viewmodel:
public RestClient()
{
client = new HttpClient
{
MaxResponseContentBufferSize = 256000
};
}
public async Task<ServiceItem> Servicetypes(int shopid)
{
var formcontent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string,string>("branch_id",Convert.ToString(shopid)),
});
var response = await client.PostAsync("http://saloonbooking.com/index.php/branch/get_single_branch_details/", formcontent);
var data = await response.Content.ReadAsStringAsync();
var status = JsonConvert.DeserializeObject<ServiceItem>(data);
return status;

Related

How to update/refresh observable collection?

My observable collection is not getting updated. Once user views post and goes back to his home page he needs to go to another page to refresh his home page to reflect his last seen article.
So far example user sees article Coffee, goes back to his HP and there is no article Coffee in the collection. Then he goes to his profile(or any other page) and then goes back to HP and there is updated collection with article coffee. I have I notifyproperty
HomePage
public ArticleBrowser()
{
InitializeComponent();
Load();
}
private async void Load()
{
BindingContext = new MyArticlesBrowserViewModel();
if (BindingContext is MyArticlesBrowserViewModel)
{
var context = new MyArticlesBrowserViewModel();
await context.LoadDataForBestSellers();
lastThreeArticlesCarouselView.ItemsSource = null;
lastThreeArticlesCarouselView.ItemsSource = context.LastThreeArticles;
bestSellersCarouselView.ItemsSource = context.ListOfBestSellers;
}
}
<local:ExtendedCarouselViewControl x:Name="lastThreeArticlesCarouselView"
Grid.Row ="1"
HeightRequest="250"
ShowIndicators="True"
Margin="0"
VerticalOptions="Start"
IndicatorsTintColor="{ DynamicResource TranslucidBlack }"
CurrentPageIndicatorTintColor="{ DynamicResource BaseTextColor }"
ItemsSource="{ Binding LastThreeArticles, Mode=TwoWay }">
<cv:CarouselViewControl.ItemTemplate>
<DataTemplate>
<local:AvatArticlesBrowserHeaderItemTemplate />
</DataTemplate>
</cv:CarouselViewControl.ItemTemplate>
</local:ExtendedCarouselViewControl>
ViewModel
private static List<Article> _lastOpenedArticles;
private static List<DownloadedArticle> _allDownloadedArticles;
private static List<Article> _lastSeenArticles;
public ObservableCollection<ArticleDetailData> LastThreeArticles { get; } = new ObservableCollection<ArticleDetailData>();
void ShowLastListened()
{
var downloadedArticles = LangUpDataSaverLoader.DeserializeAllOptimizationData();
if (_lastOpenedArticles != null && _lastOpenedArticles.Count > 0)
{
foreach (var article in _lastOpenedArticles.Take(3))
{
var filename = string.Format(SharedConstants.ArticleImageUrl, SharedConstants.ApiBaseUri, article.Id);
var newCell = new ArticleDetailData()
{
Author = article.Author,
Description = article.Description,
Body = article.Description,
Section = article.Category,
Id = article.Id,
Subtitle = article.Description,
Title = article.NameCz,
WhenDay = article.DateCreate.Day.ToString() + " / ",
WhenMonth = article.DateCreate.Month.ToString() + " / ",
WhenYear = article.DateCreate.Year.ToString(),
FullDate = article.DateCreate.ToLongDateString(),
NumberOfWords = article.NumberOfWords,
AmountOfGrammarDescription = article.AmountOfGrammarDescription,
ArticleLength = article.ArticleLength,
Price = article.Price,
IsSubmitted = article.IsSubmitted,
BestSellerRating = article.BestSellerRating,
};
if (downloadedArticles.DownloadedArticles.Any(m => m.Id == article.Id))
{
newCell.BackgroundImage = article.Id.ArticleImageFile();
}
newCell.BackgroundImage = filename;
LastThreeArticles.Add(newCell);
}
}
}
public async Task LoadDataForBestSellers()
{
var articlesApiResponse = await AVAT.App.ApiFactory.GetBestSellerArticlesAsync();
var allArticles = articlesApiResponse.Match(articles => articles.ToList(), _ => new List<Article>());
FillArticles(allArticles);
if (LangUpLoggedUser.LoggedIn || LangUpLoggedUser.LoggedOffline)
{
LastThreeArticles.Clear();
var lastOpenedArticle = LangUpDataSaverLoader.DeserializeLastLoadedArticle();
lastOpenedArticle.Reverse();
_lastOpenedArticles = lastOpenedArticle;
ShowLastListened();
}
else
{
var freeArticlesApiResponse = await AVAT.App.ApiFactory.GetAllFreeArticlesAsync();
var allUserArticles = articlesApiResponse.Match(articles => articles.ToList(), _ => new List<Article>());
FillAnonymousArticles(allUserArticles);
}
}
I have tried Refresh Command but i was not getting any data back
public ICommand RefreshCommand { get; }
public MyArticlesBrowserViewModel()
: base()
{
RefreshCommand = new Command(async () => await ExecuteRefreshCommand());
}
async Task ExecuteRefreshCommand()
{
if (IsBusy) return;
IsBusy = true;
try
{
await LoadDataForBestSellers();
}
finally
{
IsBusy = false;
}
}
Solved with
protected override void OnAppearing()
{
base.OnAppearing();
var context = new MyArticlesBrowserViewModel();
lastThreeArticlesCarouselView.ItemsSource = null;
Task.Run(async () => await context.LoadDataForBestSellers()).Wait();
bestSellersCarouselView.ItemsSource = context.ListOfBestSellers;
lastThreeArticlesCarouselView.ItemsSource = context.LastThreeArticles;
}

Initialize an xamarin view after an async method

Good evening everyone.
For some time now I have been to Xamarin. My first tests are rather conclusive. I decided to try to make a small application that retrieves information in a database via an API and then update this data via a ListView.
When I launch the application on my emulator everything works but as soon as I install the application on my phone it crashes. I thought this was because the API but I have an API that I use to check the Login / password that works correctly.
The API that returns the data reviews a lot of line about 3500/4000, can this be the reason?
So I passed the loading of the data in my viewModel in an async method but the problem now is that the view loads before the data is loaded correctly. Is there a way to get the view initialized after the data is loaded?
Below my code.
Initializing my viewModel
class ManageInventViewModel
{
public ObservableCollection<InventViewModel> InventProduct { get; set; }
public Command<InventViewModel> UpdateCommand
{
get
{
return new Command<InventViewModel>(invent =>
{
var index = invent.IndexLigneInventaire;
InventProduct.Remove(invent);
InventProduct.Insert(index, invent);
});
}
}
public Command<InventViewModel> ResetStock
{
get
{
return new Command<InventViewModel>(invent =>
{
var index = InventProduct.IndexOf(invent);
InventProduct.Remove(invent);
invent.RealStockProduct = 0;
InventProduct.Insert(index, invent);
});
}
}
public ManageInventViewModel()
{
LoadInventaire();
}
private async void LoadInventaire()
{
var listMvt = await Utils.Utils.GetListMouvementUntilDate();
var listStock = Utils.Utils.GetStockByProduct(listMvt).Take(20);
InventProduct = new ObservableCollection<InventViewModel>();
var indexLine = 0;
foreach (var stock in listStock)
{
var inventViewModel = new InventViewModel
{
LibelleProduit = stock.LibelleProduit,
PrCodeProduit = stock.PrCodeProduit,
UpCodeProduit = stock.UpCodeProduit,
RealStockProduct = stock.StockTheoProdct,
StockTheoProdct = stock.StockTheoProdct,
IndexLigneInventaire = indexLine
};
++indexLine;
InventProduct.Add(inventViewModel);
}
}
}
Initializinz my view
public partial class InventPage : ContentPage
{
public InventPage()
{
InitializeComponent();
TableInvent.ItemSelected += (sender, e) =>
{
if (TableInvent.SelectedItem != null)
{
if (TableInvent.SelectedItem is InventViewModel item)
{
PopupNavigation.Instance.PushAsync(new ChangeStockModal(item, this));
}
TableInvent.SelectedItem = null;
}
};
}
private void Reset_Stock(object sender, EventArgs e)
{
var input = sender as Button;
var inventViewModel = input?.BindingContext as InventViewModel;
var listViewModel = BindingContext as ManageInventViewModel;
listViewModel?.ResetStock.Execute(inventViewModel);
}
public void Update_Stock_List(InventViewModel dataStockUpdate)
{
var listViewModel = BindingContext as ManageInventViewModel;
listViewModel?.UpdateCommand.Execute(dataStockUpdate);
PopupNavigation.Instance.PopAsync();
}
}
Thanks
I managed to create the ActivityIndicator but I can not get my data loaded while I'm displaying the wait screen.
Regarding this issue, I don't see you useActivityIndicator from your code,maybe you didn't update your code, I think if you use useActivityIndicator , You can bind one property to ActivityIndicator IsRunning and IsVisible, then you can solve your issue.
Related use ActivityIndicator step, you can take a look:
ActivityIndicator

XAMARIN FORM : How to programmatically open page and scroll down and hightlight viewcell of listview when open firebase notification

i have create app in which user assign a task to other user, when user assign a task the other use get notification that you have been assigned a new task this is my code
public void NewTaskNotification()
{
try
{
var result = "-1";
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://fcm.googleapis.com/fcm/send");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add(string.Format("Authorization: key={0}", "AAAAHiXg3GM:APA91bFhpVU5meuhVtbHUzIgd7Ualwdi8PROKbXIf0Y_tU9sxI71vPdiInOpRgribAUuqpuqn5hmaZV7ZwQTGv2KKERsKGYOwjkwZIqssWYiYNh7IrjhfnBR0XJj7t-GW7GqvEHVs0Q"));
httpWebRequest.Headers.Add(string.Format("Sender: id={0}", "129484512355"));
httpWebRequest.Method = "POST";
var payload = new
{
to = device_token.Text,
priority = "high",
content_available = true,
notification = new
{
body = "You have been assigned a new task " + "(" + TaskName.Text + ") by " + EmployeeName.Text,
title = "New Task",
icon = "Icon.png"
},
data = new
{
open_page = "NewTask",
new_task="newNotification",
},
};
App.cs
protected override void OnStart()
{
CrossFirebasePushNotification.Current.OnNotificationOpened += (s, p) =>
{
if (p.Data["open_page"].ToString() == "NewTask")
{
//var mdMasterPage = new MainPage { Title = "master page" };
//var mdp = new MasterDetailPage();
//mdp.Master = mdMasterPage;
//mdp.Detail = new NavigationPage((Page)Activator.CreateInstance(typeof(ToDo)));
//Application.Current.MainPage = mdp;
MainPage = new NavigationPage(new TabbedMainPage())
{
BarBackgroundColor = Color.FromHex("#C6488D"),
BarTextColor = Color.White
};
}
currenly when i open notification its just open the page and dont hit the speicific row of listview which is link to this notification i need to solve this issue but i am stuck how to do that
You can use the method ScrollTo.
From the documentation, you can specify the item that you want to scroll into.

Xamarin Prism cannot navigate with parameters

for my app i create my own buttons using a frame and adding a tapgesture to it. here i use the navigation of prism to go to a specific page with a parameter. however. the viewmodel i'm going to does not trigger the Navigated to method. here is some code.
during debugging it seems that the adding of the parameters is no problem. however the constructor for the viewmodel is called instead.
button
public class FolderButton : Frame
{
public FolderButton(Folder folder, INavigationService navigationService)
{
var navParams = new NavigationParameters();
navParams.Add("folder", folder);
GestureRecognizers.Add(new TapGestureRecognizer()
{
Command = new Command(async () => { await navigationService.NavigateAsync("FolderInventory", navParams); }),
});
BackgroundColor = Color.CornflowerBlue;
var thickness = new Thickness();
thickness.Bottom = 10;
thickness.Left = 10;
thickness.Right = 10;
thickness.Top = 10;
Margin = thickness;
CornerRadius = 5;
var completeStack = new StackLayout();
var imgStack = new StackLayout();
imgStack.Padding = thickness;
imgStack.Children.Add(new Image { Source = "folder.png" });
completeStack.Children.Add(imgStack);
var lblStack = new StackLayout();
lblStack.Padding = thickness;
lblStack.Children.Add(new Label
{
Text = folder.Name,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Start
});
completeStack.Children.Add(lblStack);
Content = completeStack;
}
}
called viewmodel
public class FolderInventoryViewModel : BindableBase, INavigatedAware
{
public Folder Folder => _folder;
private readonly INavigationService _navigationService;
private Folder _folder;
private readonly ISQLiteService _sqlService;
private List<Frame> _buttons;
public List<Frame> Buttons
{
get => _buttons;
set => _buttons = value;
}
public FolderInventoryViewModel(Folder folder, INavigationService navigationService, ISQLiteService sqlService)
{
_folder = folder;
_sqlService = sqlService;
_navigationService = navigationService;
GetItemsForFolder();
}
private void GetItemsForFolder()
{
var itemList = _sqlService.GetAllFolderItems(Folder.Name);
foreach (var item in itemList)
{
var itemButton = new ItemButton(_navigationService, item);
_buttons.Add(itemButton);
}
}
public void OnNavigatedFrom(NavigationParameters parameters)
{
if (parameters["folder"] is Folder folder)
{
_folder = folder;
}
}
public void OnNavigatedTo(NavigationParameters parameters)
{
if (parameters["folder"] is Folder folder)
{
_folder = folder;
}
}
}
This is not the essence of using the framework. To properly use the Prism with its NavigationParameters you first properly maintain the MVVM idea behind it.
E.g.
<Button Command="{Binding testCommand}" text="TestButton"/>
Your ViewModel (Pardon about this, you need to inject NavigationService to your ViewModel's constructor)
private DelegateCommand _testCommand;
public DelegateCommand testCommand =>
_testCommand?? (_testCommand= new DelegateCommand(ExecuteTest));
private void ExecuteTest()
{
NavigationParameters navigationParameters = new NavigationParameters();
navigationParameters.Add("yourParameterId", value);
NavigationService.NavigateAsync("YourPage", navigationParameters);
}
And then onto your next page
Inherit INavigationAware to your NextPage : YourNextPage: BaseViewModel, INavigationAware
INavigationAware has 3 methods NavigatingTo, NavigatedTo, NavigatedFrom
Inside OnNavigatedTo you can call the parameters you have passed
public void OnNavigatedTo(NavigationParameters parameters)
{
//You can check if parameters has value before passing it inside
if(parameters.ContainsKey("YourParameterId")
{
yourItem = (dataType)parameters[YourParameterId];
}
}
Also note: The constructor will always be called first before the Navigating methods

Dynamics CRM Solution Import via SDK is not working

I have the below code that imports a solution into CRM Dynamics.
The code executes successfully and the import job data returns a result of success. How ever when I look for the solution in Settings->Solutions it is not there. Can anyone suggest a fix?
private void ImportSolution(string solutionPath)
{
byte[] fileBytes = File.ReadAllBytes(solutionPath);
var request = new ImportSolutionRequest()
{
CustomizationFile = fileBytes,
ImportJobId = Guid.NewGuid()
};
var response = _settings.DestinationSourceOrgService.Execute(request);
var improtJob = new ImportJob(_settings);
var importJobResult = improtJob.GetImportJob(request.ImportJobId);
var data = importJobResult.Attributes["data"].ToString();
var jobData = new ImportJobData(data);
var filePath = $#"{this._settings.SolutionExportDirectory}\Logs\";
var fileName = $#"{filePath}{jobData.SolutionName}.xml";
Directory.CreateDirectory(filePath);
File.WriteAllText(fileName, data);
PrintResult(jobData.Result, jobData.SolutionName);
}
public class ImportJob
{
private readonly ConfigurationSettings _settings;
public ImportJob(ConfigurationSettings settings)
{
_settings = settings;
}
public Entity GetImportJob(Guid importJobId)
{
var query = new QueryExpression
{
EntityName = "importjob",
ColumnSet = new ColumnSet("importjobid", "data", "solutionname"),
Criteria = new FilterExpression()
};
var result = _settings.DestinationSourceOrgService.Retrieve("importjob", importJobId, new ColumnSet("importjobid", "data", "solutionname", "progress"));
return result;
}
}
Thre ImportSolutionResponse does not contain any information as per the screen shot below.

Resources