Binding dropdown when ajax form in submitted in mvc2 asp.net - asp.net-mvc-2

My requirement is simple, there are two dropdowns in my view. First dropdown is filled be default and second dropdown has to be filled based on values from first dropdown.
My view is
<script type='text/javascript'>
$(function() {
$('#ddlRoles').change(function() {
$(this).parents('form').submit();
});
});
< % using (Ajax.BeginForm("UpdateDropdownForm", new AjaxOptions { UpdateTargetId = "txtDropdownValue" }))
{ %>
<%= Html.DropDownList("ddlRoles", (IEnumerable<SelectListItem>)ViewData["RolesData"])%>
<%= Html.DropDownList("ddlUsers", (IEnumerable<SelectListItem>)ViewData["UsersList"])%>
<% } %>
My controller is
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["RolesData"] = GetDropdownList();
List<SelectListItem> usersList = new List<SelectListItem>();
usersList.Add(new SelectListItem() { Text = "Select" });
ViewData["UsersList"] = usersList;
TempData["UsersList"] = usersList;
return View();
}
public IEnumerable<SelectListItem> UpdateDropdownForm(string ddlRoles)
{
ViewData["UsersList"] = GetUsersList();
TempData["UsersList"] = GetUsersList();
return GetUsersList();
}
public List<SelectListItem> GetDropdownList()
{
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem() { Text = "Admin", Value = "1" });
list.Add(new SelectListItem() { Text = "Employee", Value = "2" });
list.Add(new SelectListItem() { Text = "Manager", Value = "3" });
return list;
}
public List<SelectListItem> GetUsersList()
{
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem() { Text = "Administrator", Value = "10" });
list.Add(new SelectListItem() { Text = "Ramesh", Value = "20" });
list.Add(new SelectListItem() { Text = "Satish", Value = "30" });
return list;
}
}
Here, im able to post the first dropdown data, and im setting the second dropdown data in viewdata/tempdata and in view im binding the data to second dropdown. But this is not working.
For now, when first dropdown is changed, im just binding second dropdown. but what if i want to fill a dropdown and display data in two text boxes. What do i have to do in that case?
How do i solve this.
please help.

You may find the following answer useful for generating cascading dropdown lists.

Related

xamarin forms picker binding selected value to NgModel like angular

I have a dynamic model of the user entity with JSON type. I need to show a form to select the value foreach property with dropdownlist then insert to the db. Like a entity of user has property sex and age(property can be edit by endpage by customer) .
the example result like below:
[
{
"bindValue": null,
"title": "sex",
"code":"sex",
"property": {
"option": [
"male",
"female"
]
}
},
{
"bindValue": null,
"code":"grade",
"property": {
"option": [
"2",
"3"
]
}
}
]
with angular ionic project i can code with this:
<ng-container *ngFor="let x of dynamicdroplist">
<ion-item>
<ion-label fixed>{{x.title}}</ion-label>
<ion-select [(ngModel)]="x.bindValue">
<ion-select-option *ngFor="let y of x.property.option" value="{{y}}">{{y}}</ion-select-option>
</ion-select>
</ion-item>
</ng-container>
when user change the select value, it'll bind "ngModel" to x.bindvalue, i can filter the code and the binvalue data to send to api.
But with xamarin forms i don't know how to bind select value to bindvalue
foreach(var item in field){
StackLayout layout = new StackLayout().LoadFromXaml("<StackLayout></StackLayout>");
layout.Children.Add(new Label().LoadFromXaml("<Label Text=\"" + item.Title + "\"></Label>"));
var picker = new Picker { Title = item.Title };
foreach (var e in item.Property.option)
{
picker.Items.Add(e);
}
layout.Children.Add(picker);
_stackLayout.Children.Add(layout);
}
I want to know how can i code this with xamarin forms?
You can bind the Picker.SelectedItem to bindValue in TwoWay, then if user change the select value, the bindValue in the model will update:
picker.BindingContext = item;
picker.SetBinding(Picker.SelectedItemProperty, "bindValue",mode:BindingMode.TwoWay);
Here is the a sample code you can refer:
public partial class MainPage : ContentPage
{
StackLayout _stackLayout;
List<RootObject> field = new List<RootObject>();
public MainPage()
{
InitializeComponent();
_stackLayout = new StackLayout();
field.Add(new RootObject() { bindValue = "", title = "sex", code ="sex", property = new Property() { option = new List<string>() { "male","female"} } });
field.Add(new RootObject() { bindValue = "", title = "grade", code = "grade", property = new Property() { option = new List<string>() { "2", "3" } } });
foreach (RootObject item in field)
{
StackLayout layout = new StackLayout();
layout.Children.Add(new Label() { Text = item.title });
var picker = new Picker { Title = item.title };
//set the BindingContext here
picker.BindingContext = item;
foreach (string e in item.property.option)
{
picker.Items.Add(e);
//bind the value here
picker.SetBinding(Picker.SelectedItemProperty, "bindValue",mode:BindingMode.TwoWay);
}
layout.Children.Add(picker);
picker.SelectedIndexChanged += Picker_SelectedIndexChanged;
_stackLayout.Children.Add(layout);
}
Content = _stackLayout;
}
private void Picker_SelectedIndexChanged(object sender, EventArgs e)
{
//check the value change in field
RootObject r1 = field[0];
Console.WriteLine(r1.bindValue);
RootObject r2 = field[1];
Console.WriteLine(r2.bindValue);
}
}
public class Property
{
public List<string> option { get; set; }
}
public class RootObject
{
public string bindValue { get; set; }
public string title { get; set; }
public string code { get; set; }
public Property property { get; set; }
}
Refer: data-binding
If you need the value programatically, just access it using the picker variable you declared;
picker.SelectedItem
Otherwise if you want to bind it to the UI, you can;
myLabel.SetBinding(Label.TextProperty, new Binding("SelectedItem", source: picker));

Updating related Phone entities with custom tag helper

As my application currently sits, each AppUser may (or may not) have 3 phone numbers (UserPhones). One of each type (Mobile, Home, Other).
The following Tag Helper works great (Thanks #itminus).
Calling code from Razor Page:
<user-phones phones="#Model.UserPhones"
asp-for="#Model.UserPhones"
prop-name-to-edit="PhoneNumber"
types-to-edit="new EnumPhoneType[] { EnumPhoneType.Mobile,
EnumPhoneType.Other }" />
Code:
public class UserPhonesTagHelper : TagHelper
{
private readonly IHtmlGenerator _htmlGenerator;
private const string ForAttributeName = "asp-for";
[HtmlAttributeName("expression-filter")]
public Func<string, string> ExpressionFilter { get; set; } = e => e;
public List<UserPhones> Phones { get; set; }
public EnumPhoneType[] TypesToEdit { get; set; }
public string PropNameToEdit { get; set; }
[ViewContext]
public ViewContext ViewContext { set; get; }
[HtmlAttributeName(ForAttributeName)]
public ModelExpression For { get; set; }
public UserPhonesTagHelper(IHtmlGenerator htmlGenerator)
{
_htmlGenerator = htmlGenerator;
}
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
output.TagName = null; //DO NOT WANT AN OUTTER HTML ELEMENT
for (int i = 0; i < Phones.Count(); i++)
{
var props = typeof(UserPhones).GetProperties();
var pType = props.Single(z => z.Name == "Type");
var pTypeVal = pType.GetValue(Phones[i]);
EnumPhoneType eType = (EnumPhoneType) Enum.Parse(typeof(EnumPhoneType), pTypeVal.ToString());
string lVal = null;
switch (eType)
{
case EnumPhoneType.Home:
lVal = "Home Phone";
break;
case EnumPhoneType.Mobile:
lVal = "Mobile Phone";
break;
case EnumPhoneType.Other:
lVal = "Other Phone";
break;
default:
break;
}
//LOOP ALL PROPERTIES
foreach (var pi in props)
{
var v = pi.GetValue(Phones[i]);
var expression = this.ExpressionFilter(For.Name + $"[{i}].{pi.Name}");
var explorer = For.ModelExplorer.GetExplorerForExpression(typeof(IList<UserPhones>), o => v);
//IF REQUESTED TYPE AND PROPERTY SPECIFIED
if (pi.Name.NormalizeString() == PropNameToEdit.NormalizeString() && TypesToEdit.Contains(eType))
{
TagBuilder gridItem = new TagBuilder("div");
gridItem.Attributes.Add("class", "rvt-grid__item");
gridItem.InnerHtml.AppendHtml(BuildLabel(explorer, expression, lVal));
gridItem.InnerHtml.AppendHtml(BuildTextBox(explorer, expression, v.ToString()));
output.Content.AppendHtml(gridItem);
}
else //ADD HIDDEN FIELD SO BOUND PROPERLY
output.Content.AppendHtml(BuildHidden(explorer, expression, v.ToString()));
}
}
}
private TagBuilder BuildTextBox(ModelExplorer explorer, string expression, string v)
{
return _htmlGenerator.GenerateTextBox(ViewContext, explorer, expression, v, null, new { #class = "form-control" });
}
public TagBuilder BuildHidden(ModelExplorer explorer, string expression, string v)
{
return _htmlGenerator.GenerateHidden(ViewContext, explorer, expression, v, false, new { });
}
public TagBuilder BuildLabel(ModelExplorer explorer, string expression, string v)
{
return _htmlGenerator.GenerateLabel(ViewContext, explorer, expression, v, new { });
}
}
My Question:
Lets assume this AppUser only has one related Mobile phone number listed currently. So AppUser.UserPhones (count = 1 of type Mobile). So the code above, as-is, will only render an input for Mobile phone.
Since types-to-edit calls for both Mobile and Other, I want both inputs to be rendered to the screen. And IF the user adds a phone number to the Other input, then it would be saved to the related UserPhones entity on the Razor Pages OnPostAsync method. If the user does NOT provide a number for the "Other" input, then the related UserPhones record of type "Other" should NOT be created.
Can you help?
Thanks again!!!!
TagHelper
As my application currently sits, each AppUser may (or may not) have 3 phone numbers (UserPhones). One of each type (Mobile, Home, Other).
If I understand correctly, an AppUser might have 3 phone numbers and the count of each phone type for every user will be zero or one.
If that's the case, we can simply use PhoneType as an index, in other words, there's no need to use a custom index to iterate through the Phones property, and the ProcessAsync() method could be :
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
output.TagName = null; //DO NOT WANT AN OUTTER HTML ELEMENT
var props = typeof(UserPhones).GetProperties();
// display editable tags for phones
foreach (var pt in this.TypesToEdit) {
var phone = Phones.SingleOrDefault(p=>p.Type == pt);
var index = (int) pt;
foreach (var pi in props)
{
// if phone==null , then the pv should be null too
var pv = phone==null? null: pi.GetValue(phone);
var tag = GenerateFieldForProperty(pi.Name, pv, index, pt);
output.Content.AppendHtml(tag);
}
}
// generate hidden input tags for phones
var phones= Phones.Where(p => !this.TypesToEdit.Contains((p.Type)));
foreach (var p in phones) {
var index = (int)p.Type;
foreach (var pi in props) {
var pv = pi.GetValue(p);
var tag = GenerateFieldForProperty(pi.Name,pv,index,p.Type);
output.Content.AppendHtml(tag);
}
}
}
Here the GenerateFieldForProperty is a simply helper method to generate tag builder for particular property:
private TagBuilder GenerateFieldForProperty(string propName,object propValue,int index, EnumPhoneType eType )
{
// whether current UserPhone is editable (check the PhoneType)
var editable = TypesToEdit.Contains(eType);
var expression = this.ExpressionFilter(For.Name + $"[{index}].{propName}");
var explorer = For.ModelExplorer.GetExplorerForExpression(typeof(IList<UserPhones>), o => propValue);
//IF REQUESTED TYPE AND PROPERTY SPECIFIED
if (pi.Name.NormalizeString() == PropNameToEdit.NormalizeString() && editable)
{
TagBuilder gridItem = new TagBuilder("div");
gridItem.Attributes.Add("class", "rvt-grid__item");
var labelText = this.GetLabelTextByPhoneType(eType);
gridItem.InnerHtml.AppendHtml(BuildLabel(explorer, expression, labelText));
gridItem.InnerHtml.AppendHtml(BuildTextBox(explorer, expression, propValue?.ToString()));
return gridItem;
}
else //ADD HIDDEN FIELD SO BOUND PROPERLY
return BuildHidden(explorer, expression, propValue?.ToString());
}
private string GetLabelTextByPhoneType(EnumPhoneType eType) {
string lVal = null;
switch (eType)
{
case EnumPhoneType.Home:
lVal = "Home Phone";
break;
case EnumPhoneType.Mobile:
lVal = "Mobile Phone";
break;
case EnumPhoneType.Other:
lVal = "Other Phone";
break;
default:
break;
}
return lVal;
}
When posted to server, if someone doesn't input a phone number for the other PhoneType, the actual payload will be something like:
AppUser.UserPhones[0].UserPhoneId=....&AppUser.UserPhones[0].PhoneNumber=911&....
&AppUser.UserPhones[2].UserPhoneId=&AppUser.UserPhones[2].PhoneNumber=&AppUser.UserPhones[2].Type=&AppUser.UserPhones[2].AppUserId=&AppUser.UserPhones[2].AppUser=
&AppUser.UserPhones[1].UserPhoneId=...&AppUser.UserPhones[1].PhoneNumber=119&....
Since we use phone type as the index, we can conclude that the UserPhones[0] will be used as an Mobile phone and the UserPhones[2] will be treated as an Home phone.
page handler or action method
And the model binder on server side will create a empty string for each UserPhone.
To remove those empty inputs and prevent overposting attack, we could use Linq to filter UserPhones so that we can create or update UserPhone records without empty Phones:
var editables = new[] {
EnumPhoneType.Mobile,
EnumPhoneType.Other,
};
AppUser.UserPhones = AppUser.UserPhones
.Where(p => !string.IsNullOrEmpty(p.PhoneNumber)) // remove empty inputs
.Where(p => editables.Contains(p.Type) ) // remove not editable inputs
.ToList();
// now the `UserPhones` will be clean for later use
// ... create or update user phones as you like
Let's say you want to create phones :
public IActionResult OnPostCreate() {
var editables = new[] {
EnumPhoneType.Mobile,
EnumPhoneType.Other,
};
AppUser.UserPhones = AppUser.UserPhones
.Where(p => !string.IsNullOrEmpty(p.PhoneNumber))
.Where(p => editables.Contains(p.Type) )
.Select(p => { // construct relationship for inputs
p.AppUser = AppUser;
p.AppUserId = AppUser.Id;
return p;
})
.ToList();
this._dbContext.Set<UserPhones>().AddRange(AppUser.UserPhones);
this._dbContext.SaveChanges();
return Page();
}
Test Case :
<form method="post">
<div class="row">
<user-phones
phones="#Model.AppUser.UserPhones"
asp-for="#Model.AppUser.UserPhones"
prop-name-to-edit="PhoneNumber"
types-to-edit="new EnumPhoneType[] { EnumPhoneType.Mobile, EnumPhoneType.Other}"
>
</user-phones>
</div>
<button type="submit">submit</button>
</form>
User1 who has Mobile phone and Home phone number:
User2 who wants to create a new Mobile phone number :

How to update list view from another class in Xamarin forms?

I have created a list view in one class and called delete method from another class. Listview getting call but not updating list view if i call from another class. But its getting update when i call inside the same class. How to solve this issue?
namespace New
{
public partial class WishesPage : ContentPage
{
ListView listView = new ListView();
public WishesPage()
{
InitializeComponent();
var arr = JToken.Parse(ids);
foreach (var ite in arr.Children())
{
var itemProperties = ite.Children<JProperty>();
string contactElement = itemProperties.FirstOrDefault(x => x.Name == "contact").Value.ToString();
sample.Add(contactElement);
}
listView.ItemTemplate = new DataTemplate(typeof(CustomListCell));
listView.ItemsSource = sample;
Content = new StackLayout
{
Children =
{
listView,
}
};
}
public async Task delete(string wishid)
{
indicator.IsRunning = true;
var client = new HttpClient();
client.BaseAddress = new Uri("http:……”);
if (response == "success")
{
listView.ItemsSource = null;
listView.ItemsSource = sample;
}
}
}
public class CustomListCell : ViewCell
{
public CustomListCell()
{
wishIdLabel.SetBinding(Label.TextProperty, new Binding("contact"));
horizontalLayout.Children.Add(wishIdLabel);
var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true };
deleteAction.Clicked += async (sender, e) =>
{
WishesPage wishes = new WishesPage();
wishes.delete(wishId);
};
ContextActions.Add(deleteAction);
}
}
}
I have updated this repo that explain how to use Commands inside a ViewCell.
In your case, you should move the construction of ViewCell inside the ContentPage. Something like
lv.ItemTemplate = new DataTemplate(() =>
{
StackLayout slView = new StackLayout();
Label lDesc = new Label();
lDesc.SetBinding(Label.TextProperty, "Description", stringFormat: "DESCRIPTION: {0}");
var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true }; // red background
deleteAction.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.TrashCommand", source: this));
deleteAction.SetBinding(MenuItem.CommandParameterProperty, ".");
slView.Children.Add(lDesc);
ViewCell vc = new ViewCell() {View = slView };
vc.ContextActions.Add(deleteAction);
return vc;
}
Now, when you longpress the row, a ContextAction "Delete" appears and a TrashCommand in your ViewModel is executed (you should use MVVM...), a "these" parameter is passed (the selected obj) so you can delete it from the List
this.TrashCommand = new Command(async (object obj) => {
try
{
if (_isTapped)
return;
if (obj != null)
System.Diagnostics.Debug.WriteLine("Obj is not null");
else
System.Diagnostics.Debug.WriteLine("Obj IS null");
_isTapped = true;
var ret = await Application.Current.MainPage.DisplayAlert("Attention", "Delete this row?", "Yes", "No");
if (ret)
{
// List is your "sample" list... Removing the obj, is it reflected to ListView if you use ObservableCollection instead of List
List.Remove((Model)obj);
Count = List.Count;
}
_isTapped = false;
}
catch (Exception ex) {
_isTapped = false;
await Application.Current.MainPage.DisplayAlert("Attention", ex.Message, "Ok");
}
});
}

Entity Framework is not providing me IDs when calling back

I'm using a ViewModel (RoleVM) with a collection of ViewModels (RolePermissionVM) for this particular edit view. The view displays the RoleVM fields, and a checkbox list of RolePermissionVM. Each row in the checkbox list has a hiddenFor for the ID of the RolePermission.
When I save the form, my controller correctly writes the data to the database, adding or updating records. However, I would like the user to remain on the page, so I call the View again, but trying to get an updated model so that I have the IDs for any newly created RolePermissionVM objects. I am not getting the new IDs into the HiddenFor fields.
Here's my class:
public class RolePermissionVM
{
public int? RolePermissionId { get; set; }
public int RoleId { get; set; }
public int PermissionId { get; set; }
public string PermissionName { get; set; }
public bool IsActive { get; set; }
}
My controller code:
private RoleVM GetRoleVm(int id)
{
var thisRoleVm = (from r in db.Role
where r.RoleId == id
select new RoleVM
{
RoleId = r.RoleId,
RoleName = r.RoleName,
RoleDescription = r.RoleDescription,
OwnerId = r.OwnerId,
IsActive = r.IsActive
}).FirstOrDefault();
thisRoleVm.RolePermission = (from p in db.Permission
join rPerm in
(from rp in db.RolePermission
where rp.RoleId == id
select rp)
on p.PermissionId equals rPerm.PermissionId into pp
from rps in pp.DefaultIfEmpty()
select new RolePermissionVM
{
RolePermissionId = (int?)rps.RolePermissionId,
RoleId = id,
PermissionId = p.PermissionId,
PermissionName = p.PermissionName,
IsActive = (rps.IsActive == null ? false : rps.IsActive)
})
.OrderBy(p => p.PermissionName).ToList();
return thisRoleVm;
}
[HttpPost, ActionName("_roleedit")]
[ValidateAntiForgeryToken]
public ActionResult _RoleEdit(RoleVM editedRole)
{
//...
if (ModelState.IsValid)
{
var dbRole = db.Role.Find(editedRole.RoleId);
dbRole.RoleName = editedRole.RoleName;
dbRole.RoleDescription = editedRole.RoleDescription;
dbRole.OwnerId = editedRole.OwnerId;
foreach (var thisPerm in editedRole.RolePermission) // RolePermission here is the ViewModel, not the actual model
{
if (thisPerm.RolePermissionId != null && thisPerm.RolePermissionId > 0)
{
// We have a record for this, let's just update it
var thisRolePerm =
dbRole.RolePermission.FirstOrDefault(rp => rp.RolePermissionId == thisPerm.RolePermissionId);
thisRolePerm.IsActive = thisPerm.IsActive;
db.Entry(thisRolePerm).State = EntityState.Modified;
}
else
{
if (thisPerm.IsActive)
{
// New and active, so we add it
dbRole.RolePermission.Add(new RolePermission
{
RoleId = editedRole.RoleId,
PermissionId = thisPerm.PermissionId,
IsActive = true
});
}
}
}
db.Entry(dbRole).State = EntityState.Modified;
db.SaveChanges(User.ProfileId);
var newEditedRole = GetRoleVm(editedRole.RoleId); // We don't get the new IDs here, but I would like to
newEditedRole.ResponseMessage = "Saved Successfully";
return View(newEditedRole); // This should have the new RolePermissionId values, but it doesn't.
}
editedRole.ResponseMessage = "Error Saving";
return View(editedRole);
}
The partial view used for each row of the CheckBox list:
#using PublicationSystem.Tools
#model PublicationSystem.Areas.Admin.Models.RolePermissionVM
<li class="editorRow ui-state-default removable-row">
#using (Html.BeginCollectionItem("RolePermission"))
{
<div class="row">
#Html.HiddenFor(model => model.RolePermissionId)
#Html.HiddenFor(model => model.RoleId)
#Html.HiddenFor(model => model.PermissionId)
#Html.HiddenFor(model => model.PermissionName)
<div class="col-md-7">
#Html.DisplayFor(model => model.PermissionName, new {htmlAttributes = new {#class = "form-control"}})
</div>
<div class="col-md-3">
#Html.CheckBoxFor(model => model.IsActive, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
}
</li>
var newEditedRole = GetRoleVm(editedRole.RoleId); should be calling the database to get the updated IDs, but it does not. I think the issue is the DBContext is using a cached copy.
So, why do the new database generated IDs not get pulled back? How can I fix that? Is there a more efficient way to do this?
You have to call return RedirectToAction("ViewName") instead of return View(newEditedRole);
Another way is removing the value from the ModelState, so it will be updated on view:
ModelState.Remove("RoleId")
model.RoleId = dbRole.RoleId
I think return RedirectToAction("ViewName") is better/more reliable choice.

Monotouch: Need to add navigation item(BarButtonItem) and event in every page

Hi i am very new to iphone programming..i have used DialogViewController in my application.
In the following code , addButton.Clicked event will generate an new root element with sections(Table cell) and we can navigating to another page using these sections.
i need NavigationItem(RightBarButtonItem) and its event in every navigating pages to save the datas in current page
its very urgent!
Thanks.
Part of My Code:
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow _window;
UINavigationController _nav;
DialogViewController _RootVC;
RootElement _rootElement;
UIBarButtonItem _addButton;
UIBarButtonItem _EditButton;
DataBaseAccess da =new DataBaseAccess();
public string _name;
EntryElement StrainName;
//Load all the datas
private bool LoadMain()
{
_window = new UIWindow (UIScreen.MainScreen.Bounds);
_rootElement = new RootElement("Strain")
{
new Section()
{
(StrainName = new EntryElement ("Strain Name","Enter Name",""))
},
new Section()
{
}
};
List ();
_RootVC = new DialogViewController (UITableViewStyle.Grouped,_rootElement,true);
_nav = new UINavigationController(_RootVC);
//_EditButton= new UIBarButtonItem(UIBarButtonSystemItem.Edit);
_EditButton = new UIBarButtonItem("Delete", UIBarButtonItemStyle.Plain,null);
_addButton = new UIBarButtonItem(UIBarButtonSystemItem.Add);
_RootVC.NavigationItem.LeftBarButtonItem = _EditButton;
_RootVC.NavigationItem.RightBarButtonItem = _addButton;
_addButton.Clicked += (sender, e) =>
{
if (StrainName.Value=="")
{
return ;
}
da.Addnew (StrainName.Value);
var strain = new Strains{Name = StrainName.Value};
var strainElement = new RootElement(StrainName.Value)
{
new Section()
{
new StringElement("Name",strain.Name)
},
new Section()
{
new EntryElement("Strain Type"," Enter Type","")
},
new Section()
{
new RootElement("Dispensory")
{
new Section()
{
new EntryElement("Dispensory"," Enter Dispensory name","")
},
new Section()
{
new EntryElement("Address"," Enter Address","")
},
new Section()
{
new EntryElement("City","Enter City","")
},
new Section()
{
new EntryElement("State","Enter State","")
},
new Section()
{
new EntryElement("Zip","Enter Zip","")
},
new Section()
{
new EntryElement("Phone","Enter Phone","")
}
}
},
new Section()
{
new EntryElement("Price","Enter Price per Gram","")
},
new Section()
{
new EntryElement("Rating","Enter Rating 1-10","")
}
};
StrainName.Value = "";
_rootElement[0].Add(strainElement);
};
_EditButton.Clicked += (sender, e) =>
{
Edit_Elements();
};
_window.RootViewController = _nav;
_window.MakeKeyAndVisible ();
return true;
}
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
return LoadMain ();
}
//List the data from DB
private void List (){
DataBaseAccess Lobj_da=new DataBaseAccess();
Lobj_da.getstrains ();
List<string> strains=Lobj_da.Starins;
foreach (string name in strains)
{
var strain = new Strains{Name = name};
var strainElement = new RootElement(name)
{
new Section()
{
new EntryElement("Name",strain.Name,strain.Name)
},
new Section()
{
new EntryElement("Strain Type"," Enter Type","")
},
new Section()
{
new RootElement("Dispensory")
{
new Section()
{
new EntryElement("Dispensory"," Enter Dispensory name","")
},
new Section()
{
new EntryElement("Address"," Enter Address","")
},
new Section()
{
new EntryElement("City","Enter City","")
},
new Section()
{
new EntryElement("State","Enter State","")
},
new Section()
{
new EntryElement("Zip","Enter Zip","")
},
new Section()
{
new EntryElement("Phone","Enter Phone","")
}
}
},
new Section()
{
new EntryElement("Price","Enter Price per Gram","")
},
new Section()
{
new EntryElement("Rating","Enter Rating 1-10","")
}
};
StrainName.Value = "";
_rootElement[0].Add(strainElement);
}
}
//
//Edit Changes
void ConfigEdit (DialogViewController dvc)
{
//dvc.NavigationItem.RightBarButtonItem = new UIBarButtonItem (UIBarButtonSystemItem.Edit, delegate {
dvc.NavigationItem.LeftBarButtonItem = new UIBarButtonItem("Update", UIBarButtonItemStyle.Plain,null);
dvc.TableView.SetEditing (true, true);
ConfigDone (dvc);
// });
}
void ConfigDone (DialogViewController dvc)
{
dvc.NavigationItem.RightBarButtonItem = new UIBarButtonItem (UIBarButtonSystemItem.Done, delegate {
dvc.TableView.SetEditing (false, true);
ConfigEdit (dvc);
LoadMain();
});
}
public void Edit_Elements ()
{
RootElement _rootElement_Edit;
_rootElement_Edit = new RootElement("Strain")
{
new Section()
{
}
};
DataBaseAccess LEobj_da=new DataBaseAccess();
LEobj_da.getstrains ();
List<string> strains=LEobj_da.Starins;
foreach (string name in strains){
var strain = new Strains{Name = name};
var strainElement = new RootElement(name)
{
new Section()
{
new StringElement("Name",strain.Name)
}
};
_rootElement_Edit[0].Add(strainElement);
}
var dvc = new EditingDialog (_rootElement_Edit, true);
ConfigEdit (dvc);
_nav.PushViewController (dvc, true);
}
} `
I think the best way is the create a new DialogViewController and to implement your saving code there.
You should subclass UINavigationView and all your views should inherit form it