How to show a MvxDialogFragment from ViewModel? - xamarin.android

In this example https://github.com/MvvmCross/MvvmCross-Tutorials/tree/master/DialogExamples/DialogExamples.Droid
the MvxDialogFragment is launched from the Activity.
How can I do to show My MvxDialogFragment directly from ViemModel?
I have two ViewModels: ListViewModel And DetailViewModel
In ListViewModel:
public DetailViewModel SelectedItem
{
get { return _SelectedItem; }
set
{
_SelectedItem = value;
ShowViewModel<DetailViewModel>(new { id = value.Model.Id }); //Show my activity in Dialog mode
}
}
Thank you in advance.

I think you should look into this.
It contains an example of an MvxDialogFragment with its viewmodel

Related

ActionRequest hopping

I have been working with controllers for a while and everything is working really great.
Until now!
My current scenario is that I have is a view that contains a button which triggers JavaScript code.
That JS code then triggers a method of a controller. And here I have an if condition that returns the view or does a RedirectToAction to another controller's method, which returns a view.
When pressing that button, I see in the debugger that my code runs through all those methods, when when it comes to returning the view, nothing happens.
Below is a simplified version of my code:
<script>
jQuery.ajax({
type: "POST",
url: "#Url.Action("applyChanges", "Controller1")",
data: { jsondata: config}
});
</script>
public class Controller1: Controller {
public ActionResult applyChanges(string jsondata)
{
return RedirectToAction("validateData", "Controller2", new { id = account.id});
}
}
public class Controller2: Controller
{
public ActionResult validateData(int id)
{
if(data.stored.under.this.id == false)
{
return View("validateData");
}
else
{
return RedirectToAction("viewList", "PMGLists", new { id = id });
}
}
}
The browser simply stays as if nothing happened.
What am I missing here?

Getting identity from another method in the same class

Into class I get logged user like
public static GetUserById_Result GetUser(string userId)
{
GetUserById_Result user = new GetUserById_Result();
try
{
using (EF.SSMA oContext = new EF.SSMA())
{
user = oContext.GetUserById(userId).FirstOrDefault();
}
}
catch (Exception)
{
throw;
}
return user;
}
So it runs fine. But in the same class I want to acces user value into another method
public static List<GetUsers_Result> SelectAll()
{
List<GetUsers_Result> lstResult = new List<GetUsers_Result>();
try
{
using (EF.SSMA oContext = new EF.SSMA())
{
lstResult = oContext.GetUsers().Where().ToList();
}
}
catch (Exception ex)
{
throw ex;
}
return lstResult;
}
What I need to do to achieve that?, into controller is really simple I just do this:
var users = User.Identity.GetUserId();
GetUserById_Result currentUser = UserClass.GetUser(users);
var role = currentUser.BranchOfficeId;
But how can I acces it in the same class' I try to call GetUserId with
System.Web.HttpContext.Current.User.Identity.GetUserId();
but it just mark HttpContext in red and say "Cannot resolve symbol 'HttpContext'"
My target is to call only users who BranchOfficeId = user.BranchOfficeId
Help is very appreciated. Regards
If i understand your question well, make sure that you already installed the package Microsoft.Owin.Host.SystemWeb and add using System.Web, then use directely User.Identity.GetUserId()
The reason you can do this in the controller is because Controller has an HttpContext property, which has been created with the details of the current request, including the identity of the current user.
If you want to access the user from another class, you need to pass the user as an argument to your method. As an example:
using System.Security.Principal;
public class SomeClass
{
public void SomeMethod(IPrincipal user)
{
// Whatever you need
}
}
Then in your controller:
var someClass = new SomeClass();
someClass.SomeMethod(HttpContext.User);
However, if you're only interested in the user's name, then you can actually just pass a string instead:
public class SomeClass
{
public void SomeMethod(string username)
{
// Whatever you need
}
}
Then in your controller:
var someClass = new SomeClass();
someClass.SomeMethod(HttpContext.User.Identity.Name);

Bound CheckboxElement does not update its UI correctly

To have a bindable checkbox-list in iOS with MvvmCross, I created a view-class that holds a checkbox element, that is bound to the item viewmodel:
public class CheckListItemView : BaseView
{
public CheckListItemView()
{
var set = this.CreateBindingSet<CheckListItemView, CheckListItemViewModel>();
var item = new CheckboxElement();
set.Bind(item).For(v => v.Value).To(vm => vm.IsChecked).TwoWay();
set.Apply();
this.CheckboxElement = item;
}
public new CheckListItemViewModel ViewModel
{
get { return base.ViewModel.As<CheckListItemViewModel>(); }
set { base.ViewModel = value; }
}
public Element CheckboxElement { get; set; }
}
Unfortunately, in this case the binding is not too reliable: I have a button that checks all items checked and one that un-checks all boxes.
foreach (var checkListItemViewModel in checkList)
{
checkListItemViewModel.IsChecked = value;
}
If I keep pressing those two buttons for a time, at some point the UI does not update the checked state correctly. The values in the background are correct, though.

adding a new object to observable array in knockout mvc

I'm using knockout mapping to help map a serverside object into JSON. I have an object with numerous collections in it so I don't want to have to recreate and map each piece manually in javascript. So, I'm using knockout-mapping to do this for me.
I was having issues, so I decided to try it with a simple example, so here is what I have for an ASP.NET MVC application:
C# Model:
public class Vaccinations
{
public string Vaccination { get; set; }
public System.DateTime VaccinationDate { get; set; }
}
public class Dog
{
public string Name { get; set; }
public int Age { get; set; }
public Dog()
{
this.Vaccinations = new System.Collections.Generic.List<Vaccinations>();
}
public System.Collections.Generic.List<Vacinations> Vacinations { get; set; }
}
As you can see, each Dog has a list of vaccinations they may or may not have.
In my controller, I create and return a pre-populated Dog object:
public ActionResult Load()
{
Dog rambo = new Dog
{
Name = "Rambo",
Age = 5
};
rambo.Vacinations = new System.Collections.Generic.List<Vacinations> {
new Vacinations { Vacination = "Rabies", VacinationDate = DateTime.Now.AddYears(-1) },
new Vacinations { Vacination = "Mumps", VacinationDate = DateTime.Now.AddYears(-2) }
};
return Json(rambo, JsonRequestBehavior.AllowGet);
}
In my view (Index.cshtml), I have it set up to show the dog and a list of it's vaccinations. I want to allow the user to click on an Add Vaccination button to add a new line to the collection and allow them to enter the data.
Again, I'm using knockout.mapping to do the mapping for me. In the javascript section, this is what I have:
var ViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
self.isValid = ko.computed(function () {
return self.Name().length > 3;
});
// Operations
self.save = function () {
$.ajax({
url: "Dog/Save",
type: "post",
contentType: "application/json",
data: ko.mapping.toJSON(self),
success: function (response) {
alert(response.Status);
}
});
};
self.addVaccination = function () {
self.Vaccinations.push(new self.Vaccination()); // <--- This doesn't work and I know why, so how do I do this?
}
};
$(function () {
$.getJSON("Dog/Load", null, function (data) {
ko.applyBindings(new ViewModel(data));
});
});
My question revolves around the "addVaccination" function that I've added to the ViewModel object. How do I specify a new "Vaccination" object without having to "code" one in Javascript? That was the entire reason for me using knockout mapping so I don't have to do that. But, I don't see any other way around it.
Is there a way to access the base Vaccination object from the Vaccinations observable array so I can create a new one?
And then the final question is, how to I pass this back to my controller? I'm not sure if this will work or not.
You can't directly. But what you can do is define a Vaccination instance at the server side and return it as a the default instance.
So, you need to return the old data and the default instance.
public ActionResult Load()
{
...
var data = new {
defaultVacination = new Vacination(),
rambo = rambo,
};
return Json(data , JsonRequestBehavior.AllowGet);
}
And on the client side you receive the same data and the default instance.
var ViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data.rambo, {}, self);
var defaultInstance = data.defaultVacination;
...
self.addVaccination = function () {
// clone the default instance.
self.Vaccinations.push(ko.utils.extend({}, defaultInstance));
}
I hope it helps.

MVC grid sorting - customise links

I am using the Sort method of the MvcContrib Grid to generate sorting links, e.g.
<%= Html.Grid(Model).AutoGenerateColumns().Sort((GridSortOptions)ViewData["sort"]) %>
I have a need to change the default controller/action that’s generated by the sort method. For example,
defaultControllerName/defaultActionName/?Column=ProductId&Direction=Ascending
would change to
customControllerName/customActionName/?Column=ProductId&Direction=Ascending
I haven't been able to find any existing methods in the MVCcontribution classes that would allow me to customise the links. I’d appreciate any pointers on how to go about altering the default links as I’m still very much a MVC/C# newbie.
That's not an easy task. You will need a custom grid renderer to achieve this and override the RenderHeaderText method:
public class MyHtmlTableGridRenderer<T> : HtmlTableGridRenderer<T> where TViewModel : class
{
protected override void RenderHeaderText(GridColumn<TViewModel> column)
{
if (IsSortingEnabled && column.Sortable)
{
// TODO: generate a custom link here based on the sorting options
string text = ...
base.RenderText(text);
}
else
{
RenderText(column.DisplayName);
}
}
}
And then specify that the grid should use this renderer:
.RenderUsing(new MyHtmlTableGridRenderer<Employee>())
I wanted to provide a complete working example:
public class SortableHtmlTableGridRenderer<T> : HtmlTableGridRenderer<T> where T : class
{
readonly string _action;
readonly string _controllerName;
public SortableHtmlTableGridRenderer(string action, string controllerName)
{
_action = action;
_controllerName = controllerName;
}
protected override void RenderHeaderText(GridColumn<T> column)
{
if (IsSortingEnabled && column.Sortable)
{
string sortColumnName = GenerateSortColumnName(column);
bool isSortedByThisColumn = GridModel.SortOptions.Column == sortColumnName;
var sortOptions = new GridSortOptions
{
Column = sortColumnName
};
if (isSortedByThisColumn)
{
sortOptions.Direction = (GridModel.SortOptions.Direction == SortDirection.Ascending)
? SortDirection.Descending
: SortDirection.Ascending;
}
else //default sort order
{
sortOptions.Direction = column.InitialDirection ?? GridModel.SortOptions.Direction;
}
var routeValues = HtmlHelper.AnonymousObjectToHtmlAttributes(new {sortOptions.Column, sortOptions.Direction });
var text = HtmlHelper.GenerateLink(Context.RequestContext, RouteTable.Routes, column.DisplayName, null, _action, _controllerName, routeValues, null);
RenderText(text);
}
else
{
RenderText(column.DisplayName);
}
}
}
Usage:
.RenderUsing(new SortableHtmlTableGridRenderer<YourModelType>("Search", "Search"))

Resources