xamarin.forms binding to class property not working - xaml

In my XamarinForms project I am trying to bind a label text to a property of a class. when I pass in the object to my view the label is not being populated. can someone see what I am doing wrong?
In my view model I have
class ManagerLevelPageViewModel : INotifyPropertyChanged
{
private UserSelections _MyUserSelections;
public UserSelections MyUserSelections
{
get { return _MyUserSelections; }
set {
_MyUserSelections = value;
NotifyPropertyChanged();
}
}
public ManagerLevelPageViewModel(UserSelections _temp)
{
MyUserSelections = _temp;
MyUserSelections.selectedClientName = _temp.selectedClientName;
//myUserSelections = _myUserSelections;
//SetValues();
}
here is the class
public class UserSelections
{
public int selectedClientId { get; set; }
public string selectedClientName { get; set; }
public string selectedClientShortCode { get; set; }
public decimal selectedClientPL { get; set; }
public string TopdayIdentifier { get; set; }
}
here is the view.cs
ManagerLevelPageViewModel vm;
public ManagerLevelPage (UserSelections _myUserSelections)
{
vm = new ManagerLevelPageViewModel(_myUserSelections);
InitializeComponent ();
BindingContext = vm;
DownloadData();
}
lastly here is the xaml
<Label Text="{Binding MyUserSelections.ClientName}"/>
notify property changed
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

Related

Setting a boolean property from a 3rd party endpoint that returns a string

I am attempting to deserialize a json object using JsonConvert - the data is coming from a 3rd party API
return JsonConvert.DeserializeObject<UserRegistration>(content,
JsonSnakeCaseNameStrategySettings.Settings());
The UserRegistration class:
public class UserRegistration
{
public UserRegistrationData UserRegistration { get; set; }
}
public class UserRegistrationData
{
public int UserId { get; set; }
public string Email { get; set; }
public UserRegistrationCustomFields CustomFields { get; set; }
}
public class UserRegistrationCustomFields
{
private bool emailDelivery;
public string DeliveryTime { get; set; }
public bool EmailDelivery {
get
{
return emailDelivery;
}
set
{
emailDelivery = value.ToString() == "1";
}
}
public bool SmsDelivery { get; set; }
public string PhoneNumber { get; set; }
}
I've tried several ways, this is my current iteration. The goal is to have "EmailDelivery" be a boolean, the value from the API will always be "1" or "0". This throws a JsonReaderException: Could not convert string to boolean: 0. Path 'user_registration.custom_fields.email_delivery', line 1, position 208.
You need custom JsonConverter to modify the deserialize principle.
Change your model like below:
public class UserRegistrationCustomFields
{
public string DeliveryTime { get; set; }
public bool EmailDelivery{get;set;}
public bool SmsDelivery { get; set; }
public string PhoneNumber { get; set; }
}
Custom a JsonConverter:
public class JsonBooleanConverter : JsonConverter
{
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var value = reader.Value.ToString().ToLower().Trim();
switch (value)
{
case "1": return true;
}
return false;
}
public override bool CanConvert(Type objectType)
{
if (objectType == typeof(Boolean))
{
return true;
}
return false;
}
}
How to use:
JsonConvert.DeserializeObject<UserRegistration>(json, new JsonBooleanConverter());

How to create dropdown list in ASP.NET Core?

How to create the dropdown list in one to many relation. I want to populate the category data in Post form and then want to save using POST mode.
Here is my full code:
public class Category
{
public Category()
{
Posts = new Collection<Post>();
}
public int Id{get;set;}
public string Title { get; set; }
}
public class Post
{
public int Id
public string Title { get; set; }
public string Body { get; set; }
public Category Category { get; set; }
public int CategoryId { get; set; }
}
PostFormVM:
public class PostFormVM
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
public string Body { get; set; }
[Required]
public int CategoryId { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
Mapping is here:
public class ApplicationProfile : AutoMapper.Profile
{
public ApplicationProfile()
{
CreateMap<Category, CategoryFormVM>().ReverseMap();
CreateMap<Post, PostFormVM>().ReverseMap();
}
}
Generic Repository implementation
public class GenericRepository<T>:IGenericRepository<T> where T:class
{
private readonly ApplicationDbContext _context;
public GenericRepository(ApplicationDbContextcontext)
{
_context = context;
}
public async Task<List<T>> GetAllAsync()
{
return await _context.Set<T>().ToListAsync();
}
}
ICategoryRepository:
public interface ICategoryRepository:IGenericRepository<Category>
{
}
CategoryRepository implementation
public class CategoryRepository :GenericRepository<Category>, ICategoryRepository
{
public CategoryRepository(ApplicationDbContext context):base(context)
{
}
}
PostRepo Implementation:
public class PostRepository : GenericRepository<Post>, IPostRepository
{
public PostRepository(ApplicationDbContext context) : base(context)
{
}
}
PostController:
public class PostItemController : Controller
{
private readonly IPostRepository _postRepository;
private readonly ICategoryRepository _categoryRepository;
private readonly UserManager<ApplicationUser> _userManager;
private readonly IMapper _mapper;
public PostItemController(IPostRepository postRepository, ICategoryRepository categoryRepository, IMapper mapper, UserManager<ApplicationUser> userManager)
{
_postRepository = postRepository;
_categoryRepository = categoryRepository;
_userManager = userManager;
_mapper = mapper;
}
public IActionResult Create()
{
//Here I want to populate the category data I have used the ViewBag and ViewData here
//I am unable to get the data from the database
ViewBag.Categories= _categoryRepository.GetAllAsync();
return View(new PostFormVM());
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(PostFormVM viewModel)
{
try
{
if (!ModelState.IsValid)
return View("Create", viewModel);
if (ModelState.IsValid) {
//Here I also want to map the selected category item and save to Post table.
var post = _mapper.Map<Post>(viewModel);
post.ApplicationUserId = _userManager.GetUserId(HttpContext.User);
if (viewModel.IsEdit.Equals("false"))
{
await _postRepository.CreateAsync(post);
}
else
{
await _postRepository.UpdateAsync(post);
}
}
}
catch (Exception)
{
}
return RedirectToAction(nameof(Index));
}
I want help to populate the category data in Post Entity Create form.
You can put a breakpoint on this line ViewBag.Categories = _categoryRepository.GetAllAsync();, you can see such a result prompt Result =" {Not yet computed} ", because the method in your generic repository uses the await keyword to operate Asynchronous method, it will wait for the end of the previous process before calculating the result.
Try change you code in Generic Repository like below:
public List<T> GetAllAsync()
{
return _context.Set<T>().ToList();
}
IGenericRepository
public interface IGenericRepository<T> where T : class
{
List<T> GetAllAsync();
}
Show the Category list ,controller
public IActionResult Create()
{
IEnumerable<Category> categories = _categoryRepository.GetAllAsync();
ViewBag.Categories = categories;
return View(new PostFormVM());
}
View
<select asp-for="CategoryId" asp-items="#(new SelectList(ViewBag.Categories,"Id","Title"))"></select>
Result:

ASP.Net core web API encode string to base64

I am new to .Net Core development. I have a model:
public class CoreGoal
{
[Key]
public long CoreGoalId { get; set; }
public string Title { get; set; }
public string Effect { get; set; }
public string Target_Audience { get; set; }
public string Infrastructure { get; set; }
public virtual ICollection<Image> Images { get; set; }
public CoreGoal()
{
}
}
And Image model is as following:
public class Image
{
[Key]
public long ImagelId { get; set; }
public string Base64 { get; set; }
[ForeignKey("CoreGoalId")]
public long CoreGoalId { get; set; }
public Image()
{
}
}
I am using Repository pattern. My repository:
public interface ICoreGoalRepository
{
void CreateCoreGoal(CoreGoal coreGoal);
}
public class CoreGoalRepository : ICoreGoalRepository
{
private readonly WebAPIDataContext _db;
public CoreGoalRepository(WebAPIDataContext db)
{
_db = db;
}
//Find specific
public CoreGoal Find(long key)
{
return _db.CoreGoals.FirstOrDefault(t => t.CoreGoalId == key);
}
//Add new
public void CreateCoreGoal(CoreGoal coreGoal)
{
_db.CoreGoals.Add(coreGoal);
_db.SaveChanges();
}
}
And controller:
[Route("api/[controller]")]
public class CoreGoalController : Controller
{
private readonly ICoreGoalRepository _coreGoalRepository;
//Controller
public CoreGoalController(ICoreGoalRepository coreGoalRepository) {
_coreGoalRepository = coreGoalRepository;
}
[HttpGet("{id}", Name = "GetCoreGoal")]
public IActionResult GetById(long id)
{
var item = _coreGoalRepository.Find(id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
//Create
[HttpPost]
public IActionResult Create([FromBody] CoreGoal item)
{
if (item == null)
{
return BadRequest();
}
_coreGoalRepository.CreateCoreGoal(item);
return CreatedAtRoute("GetCoreGoal", new { id = item.CoreGoalId }, item);
}
}
On POST request for CoreGoal- While creating a new CoreGoal, I would like to convert Image model's Base64 attribute from string to byte[]. I found this (https://adrientorris.github.io/aspnet-core/manage-base64-encoding.html) blogpost, but I am not sure where Am I supposed to write this piece of code.
Can someone help me?
Initially you should chage you database model to save you binary image to db (also, it's still not good idea, but let leave it for a now):
public class Image
{
[Key]
public long ImagelId { get; set; }
[NotMapped]
public string Base64 { get; set; }
public byte[] Binary {get; set;}
[ForeignKey("CoreGoalId")]
public long CoreGoalId { get; set; }
public Image()
{
}
}
next you just should convert your image inside controller:
[HttpPost]
public IActionResult Create([FromBody] CoreGoal item)
{
if (item == null)
{
return BadRequest();
}
item.Binary = Convert.FromBase64String(item.Base64);
_coreGoalRepository.CreateCoreGoal(item);
return CreatedAtRoute("GetCoreGoal", new { id = item.CoreGoalId }, item);
}
BTW:you code still not good. It's not necessary to use Repository pattern with EF core (https://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-core/). And you should introduce two model layers: public layer and model layer. You shouldn't expose EF Core contract to outside.

Windows Phone 8.1 RT view not updating (MVVM)

I'm designing a profile page for users where they can edit their personal info. I'm using a PersonViewModel (which contains the current signed in person) to display the current info about the User. The fields to edit the user's info are bound to a validation model. After pressing the 'execute changes' button and I get a response of the server (HTTPStatusCode Ok + the altered user object), I alter the fields of the existing object according to the changes. Then I used setter injection to update my PersonViewModel... When debugging, I can see that my objects are all up-to-date but my view is still displaying the old info... What am I doing wrong?`
This is the code that get's executed when I press the button to execute my changes:
private async void ChangeInfoButton(object sender, RoutedEventArgs e)
{
User user;
List<ErrorInfo> errors;
if (_profileInformationValidationModel.TryGetUser(out user, out errors))
{
var response = await Session.Instance.DataProvider.UpdaterUserInfo(user);
if (response.IsSuccess)
{
/*SignedInUserInfo = AlteredUserInfo*/
Session.Instance.User.Information = user.Information;
_personViewModel.SetPerson(user.Information);
var d1 = new MessageDialog("Uw gegevens werden succesvol gewijzigd.");
d1.ShowAsync();
AnnulInfoButton(sender, e);
}
`
And this is the PersonViewModel:
public class PersonViewModel
{
private Person _person;
public void SetPerson(Person p)
{
_person = p;
}
public PersonViewModel(Person person)
{
_person = person;
}
public string Street
{
get { return _person.Street; }
}
public string HouseNumber
{
get { return _person.HouseNumber; }
}
public string Bus
{
get { return _person.Bus; }
}
public string Email
{
get { return _person.Email; }
}
Your view model should implement the INotifyPropertyChanged interface.
Look into using a framework like MVVM Light which does most of this work for you.
You can add it to your project using NuGet.
This is how your model and view-model should look:
public class Person
{
public string Street { get; set; }
public string HouseNumber { get; set; }
public string Bus { get; set; }
public string Email { get; set; }
}
public class PersonViewModel : System.ComponentModel.INotifyPropertyChanged
{
private Person _person;
public void SetPerson(Person person)
{
_person = person;
Street = person.Street;
HouseNumber = person.HouseNumber;
Bus = person.Bus;
Email = person.Email;
}
public PersonViewModel(Person person)
{
SetPerson(person);
}
#region Street (INotifyPropertyChanged Property)
private string _street;
public string Street
{
get { return _street; }
set
{
if (_street != value)
{
_street = value;
RaisePropertyChanged("Street");
}
}
}
#endregion
#region HouseNumber (INotifyPropertyChanged Property)
private string _houseNumber;
public string HouseNumber
{
get { return _houseNumber; }
set
{
if (_houseNumber != value)
{
_houseNumber = value;
RaisePropertyChanged("HouseNumber");
}
}
}
#endregion
#region Bus (INotifyPropertyChanged Property)
private string _bus;
public string Bus
{
get { return _bus; }
set
{
if (_bus != value)
{
_bus = value;
RaisePropertyChanged("Bus");
}
}
}
#endregion
#region Email (INotifyPropertyChanged Property)
private string _email;
public string Email
{
get { return _email; }
set
{
if (_email != value)
{
_email = value;
RaisePropertyChanged("Email");
}
}
}
#endregion
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string p)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(p));
}
}
}

bind datagrid to collection of custom objects in silverlight 4

I have a collection say NotificationHistoryCollection which is a collection of NotificationHistory objects which in turn has NotificationDetails object and collection of NotificationHistoryDetail. How do I bind NotificationDetails to a datagrid and NotificationHistoryDetail collection to another datagrid in silverlight 4.0
This should give you some idea:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
friends.Add(new Friend(){Name = "Pappu",Email = new EmailAddress(){Email = "test#test.com"}});
dgFriends.ItemsSource = Friends;
}
ObservableCollection<Friend> friends = new ObservableCollection<Friend>();
public ObservableCollection<Friend> Friends { get { return friends; } set { friends = value; } }
}
public class Friend
{
public string Name { get; set; }
public string LastName { get; set; }
public EmailAddress Email { get; set; }
}
public class EmailAddress
{
public string Email { get; set; }
}
<data:DataGrid x:Name="dgFriends" AutoGenerateColumns="False">
<data:DataGrid.Columns>
<data:DataGridTextColumn Binding="{Binding Email.Email}" Header="EmailAddress" IsReadOnly="True"></data:DataGridTextColumn>
</data:DataGrid.Columns>
</data:DataGrid>
Result: