Binding 2 dropdownlist with LINQ - asp.net

Im stuck in my project here and i really need some help!
I have 2 dropdownlists "DropDownPostal" and "DropDownCity". When the user/employee logges into the system, he gets the list of Postals in the first dropdown list. Lets say he choose a postal and tabs over to the second dropdown "city". I want city to be updated with the postal the user choose earlier. I have everything working with the login and retrieving data from the database to the DropDownPostal. But I cannot get the other DropDownCity updated with any data!
Here is my code for the event i made for the postaldropdown, Im trying to make a "onLeave" event.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Test
{
public partial class WebForm1 : System.Web.UI.Page
{
// Entity
DanxWebsiteEntities dwe = new DanxWebsiteEntities();
protected void Page_Load(object sender, EventArgs e)
{
//Dropdown postback
//DropDownListPostal.AutoPostBack = false;
//Sessions
if (Session["UserID"] == null && Session["Name"] == null)
{
Response.Redirect("Error.aspx");
}
else
{
msg1.Text = "User id: "+Session["UserID"].ToString();
msg2.Text = "User Name: " + Session["Name"].ToString();
}
//Update dropdownpostal
if (!IsPostBack)
{
//Guid is structure type
Guid id =(Guid) Session["UserID"];
DropDownListPostal.DataSource = (from custumAdr in dwe.VW_CustumAddress
where custumAdr.UserID ==(Guid)id
select custumAdr).ToList();
DropDownListPostal.DataTextField = "Postal";
DropDownListPostal.DataValueField = "UserID";
DropDownListPostal.DataBind();
}
}
protected void DropDownListPostal_SelectedIndexChanged1(object sender, EventArgs e)
{
foreach (var data in dwe.VW_CustumAddress)
if (data.Postal == DropDownListPostal.SelectedItem.ToString())
{
DropDownListBy.Text = data.City;
}
else
{
}
}
}
}
Im not even sure if this code is close to correct.
Detailed help with code will be much appreciated.
Cheers :-)

If I understood you right, you only need to change the value displayed in dropDownListCity according to the value selected in dropDownListPostal. To do so, you need to bind both dropdown lists in Page_Load and then handle the selected index when SelectedIndexChanged is triggered.
private IEnumerable<KeyValuePair<string, string>> GetData()
{
using(var dataContext = new DbEntities())
{
return dataContext.VW_CustumAddress
.ToList()
.Select(item => new KeyValuePair<string, string>(item.Postal, item.City))
.ToArray();
}
}
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback)
{
IEnumerable<KeyValuePair<string,string>> data = GetData();
//Bind Postal dropdown list
dropDownListPostal.DataSource = data.Select(kvp => kvp.Key).ToList();
// ^ Select only 'Postal' column in dropdown list.
dropDownListPostal.DataBind();
// Bind City dropdown list
// We need to bind to a key-value pair to know the correspondence between items
dropDownListCity.DataValueField = "Key";
dropDownListCity.DataTextField = "Value";
dropDownListCity.DataSource = data;
dropDownListCity.DataBind();
}
}
Now, after you bound your controls to data you only need to handle SelectedIndexChanged event of dropDownListPostal (don't forget to set AutoPostback="true" in the markup of dropDownListPostal).
EDIT: Before selecting an item, clear the selection of your dropdown list to make sure only one item is selected.
protected void OnDropDownListPostalSelectedIndexChanged(object sender, EventArgs e)
{
dropDownListCity.ClearSelection();
var postal = dropDownListPostal.SelectedValue;
var listItem = dropDownListCity.Items.FindByValue(postal);
listItem.Selected = true;
}
That should do it. Hope it helps.

Make sure DropDownListPostal has AutoPostBack = True
You have no DropDownListPostal.DataBind() in your code, so the data you're assigning to it is not being bound. Make sure this is called after the data is assigned with the .DataSource.

As you have mentioned here
//Dropdown postback
//DropDownListPostal.AutoPostBack = false;
Please make it True.
<asp:DropDownList ID="DropDownListPostal" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownListPostal_SelectedIndexChanged"></asp:DropDownList>
Instead of using DropDownListBy.Text = data.City;
You can select Dropdown list by Value also,.
DropDownListBy.SelectedValue = data.id
Hope this will help you

You can try with this code
//You must bind your datas before set Text Value
DropDownListBy.DataSource =...;
DropDownListBy.DataBind();
DropDownListBy.Text = data.City;
Link : http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.text.aspx
Or you can also
DropDownListBy.Items.Add(data.City);

Related

Adding Xamarin app a searchbar

I made a simple Xamarin Cross platform SQLite app which can inserts, updates, deletes data from a listview. I want to add a searchbar. Following this tutorial i added this on my HomePage.xaml
Now if my listview's source was a list just like in the tutorial i had to write this in HomePage.xaml.cs
private void mySearchBar_ButtonPressed(object sender, EventArgs e)
{
string searchText = mySearchBar.Text;
myListView.ItemsSource=ListViewsListSource.Where(name=>name.Contains(searchText ));
}
But i defined my listview's source like this.
using (var dataaccess= new DataAccess())
{
listaListView.ItemsSource = dataaccess.GetEmployers();
}
And GetEmployers is defined in DataAccess
public List<Employer> GetEmployers()
{
return connection.Table<Employer>().OrderBy(c => c.Lastname).ToList();
}
Now what should i write in mySearchBar_ButtonPressed ?
There are a lot of different ways to approach this. Following your own example, you could add a Search method to your DataAccess class
public List<Employer> SearchEmployers(string key)
{
return connection.Table<Employer>().Where(e => e.Lastname.Contains(key) || e.FirstName.Contains(key)).OrderBy(c => c.Lastname).ToList();
}
private void mySearchBar_ButtonPressed(object sender, EventArgs e)
{
string searchText = mySearchBar.Text;
listaListView.ItemsSource = dataaccess.SearchEmployers(searchText);
}

user.Roles.FirstOrDefault() returns DynamicProxy

OK...
I was finally making some headway with creating a User Management page using Identity 2 in Web Forms.
It was mostly moving along just fine. When suddenly I run into this issue, and it makes no sense to me.
I have an AS form with a dropdown list of Roles. That list is populated using
roleMgr.Roles.ToList();
Works Great
I use the user being edited Role to set the current selected value.
ddlUserType.SelectedValue = user.Roles.FirstOrDefault().ToString();
This WAS working like dynamite
Last week...
Now all of a sudden user.Roles.FirstOrDefault().ToString(); is returning
"System.Data.Entity.DynamicProxies.IdentityUserRole_FDDE5D267CF62D86904A3BC925D70DC410F12D5BE8313308EC89AC8537DC6375"
What he heck, man?
So I tried user.Roles.Take(1).ToString();
That returns
"System.Linq.Enumerable+d__24`1[Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole]"
I have to presume I Broke, Something...
But What?
Nothing in this code page changed at all between when it worked and then didn't.
The only thing I did related to Identity at all was Migrate a couple of fields into AspNetUsers (another whole ballgame, migrations...) which also worked like dynamite BTW.
I even went to the extreme of wiping out my Migrations and AspNet user tables entirely, and re-initializing it all.
Any suggestions ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Sperry_Parts.Models;
using Sperry_Parts.Logic;
using Microsoft.AspNet.Identity.Owin;
using Owin;
namespace Parts.Admin
{
public partial class CreateEditUser : System.Web.UI.Page
{
private bool NewUser
{
get { return ViewState["NewUser"] != null ? (bool)ViewState["NewUser"] : false; }
set { ViewState["NewUser"] = value; }
}
private string EditUser
{
get { return (string)ViewState["EditUser"]; }
set { ViewState["EditUser"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
EditUser = Session["Edit_User"].ToString();
// Access the application context and create result variables.
Models.ApplicationDbContext context = new ApplicationDbContext();
RoleActions roleAction = new RoleActions();
// Create a RoleStore object by using the ApplicationDbContext object.
var roleStore = new RoleStore<IdentityRole>(context);
// Create a RoleManager object that is only allowed to contain IdentityRole objects.
var roleMgr = new RoleManager<IdentityRole>(roleStore);
// Load the DDL of Roles
var roles = roleMgr.Roles.ToList();
ddlUserType.DataTextField = "Name";
ddlUserType.DataValueField = "Id";
ddlUserType.DataSource = roles;
ddlUserType.DataBind();
if (EditUser == "")
{
txtUserName.Enabled = true;
txtUserName.Focus();
NewUser = true;
} // End New User
else
{
// User part
var userMgr = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();
txtUserName.Enabled = false;
txtFullName.Focus();
var user = userMgr.FindByName(EditUser);
if (user != null)
{
txtUserName.Text = user.UserName;
txtUserEmail.Text = user.Email;
txtFullName.Text = user.FullName;
var hisroles = user.Roles.ToList(); // properly returns 1 item
// this is where it went off the rails - these 4 lines are debugging code
string xrole = user.Roles.FirstOrDefault().ToString();
string role2 = user.Roles.Take(1).ToString();
string trythis = xrole.ToString();
string trythis2 = role2.ToString();
// I swear, this worked last week...
ddlUserType.SelectedValue = user.Roles.FirstOrDefault().ToString();
}
} // End Editing User
} // End if (!IsPostBack)
} // End Page Load
protected void CreateUser()
{
// removed as non-relevant to question
} // End CreateUser
protected void UpdateUser()
{
// removed as non-relevant to question
} // End UpdateUser
protected void btnSave_Click(object sender, EventArgs e)
{
// removed as non-relevant to question
} // End btnSave
protected void btnCancel_Click(object sender, EventArgs e)
{
Response.Redirect("~/ManageUsers");
} // End btnCancel
} // End Class CreateEditUser
}
I ran into the same problem trying to set the value of a "Roles" DropDownList inside a GridView Control. I solved it by using:
user.Roles.First().RoleId
It just happens that my RoleId is also my role name.

How to clear all form fields from code-behind?

HTML has an input button type to reset all fields in a form to their initial state in one step: <input type="reset" ... />.
Is there a similar simple way to reset all form fields of an aspx page from code-behind? Or is it necessary to reset all controls one by one with TextBox1.Text=string.Empty, TextBox2.Text=string.Empty, etc. ?
Thanks in advance!
Update:
Context is a simple Contact/"Send us a message" page with 8 asp:TextBoxes on the page (where the user enters the name, address, phone, email, message, etc.). Then he clicks on submit, the Onclick message handler in code-behind sends an email to some administrator, and all the form fields the user filled in should be emptied and he gets a notification in a label ("Message sent blabla..."). I want to have the form fields cleared to avoid that the user clicks again on submit and the same message is sent a second time.
You need only write a fork for each type of control unless one of the control has something special that needs to be done to reset it.
foreach( var control in this.Controls )
{
var textbox = control as TextBox;
if (textbox != null)
textbox.Text = string.Empty;
var dropDownList = control as DropDownList;
if (dropDownList != null)
dropDownList.SelectedIndex = 0;
...
}
ADDITION You asked how to clear controls even ones that are buried. To do that, you should create a recursive routine like so:
private void ClearControl( Control control )
{
var textbox = control as TextBox;
if (textbox != null)
textbox.Text = string.Empty;
var dropDownList = control as DropDownList;
if (dropDownList != null)
dropDownList.SelectedIndex = 0;
...
foreach( Control childControl in control.Controls )
{
ClearControl( childControl );
}
}
So, you would call this by passing the page:
ClearControls( this );
Refer this link for more information
http://www.freshcodehub.com/Article/3/clear-all-fields-like-textbox-dropdownlist-checkbox-radiobutton-label-after-form-submission-in-aspnet-c
public void ClearControls(Control parent)
{
foreach (Control c in parent.Controls)
{
if ((c.GetType() == typeof(TextBox))) //Clear TextBox
{
((TextBox)(c)).Text = "";
}
if ((c.GetType() == typeof(DropDownList))) //Clear DropDownList
{
((DropDownList)(c)).ClearSelection();
}
if ((c.GetType() == typeof(CheckBox))) //Clear CheckBox
{
((CheckBox)(c)).Checked = false;
}
if ((c.GetType() == typeof(CheckBoxList))) //Clear CheckBoxList
{
((CheckBoxList)(c)).ClearSelection();
}
if ((c.GetType() == typeof(RadioButton))) //Clear RadioButton
{
((RadioButton)(c)).Checked = false;
}
if ((c.GetType() == typeof(RadioButtonList))) //Clear RadioButtonList
{
((RadioButtonList)(c)).ClearSelection();
}
if ((c.GetType() == typeof(HiddenField))) //Clear HiddenField
{
((HiddenField)(c)).Value = "";
}
if ((c.GetType() == typeof(Label))) //Clear Label
{
((Label)(c)).Text = "";
}
if (c.HasControls())
{
ClearControls(c);
}
}
}
using the manual approach of String.Empty for each and every Textbox or any other field will be cumbersome, also by using Response.Redirect(); it will be difficult to show any confirmation message or same. So, on reading so many blogs i have found a reliable approach so far:
Public void reset(Control control)
{
foreach (Control x in control.Controls)
{
if (x is TextBox)
{
(x as TextBox).Text = String.Empty;
}
else if (x is DropDownList)
{
(x as DropDownList).SelectedIndex = 0;
}
.
.
reset(x);
}
}
use this code as reset(this); in your page wherever you want to reset or clear the values. At end of the if conditions do not forget to use the function recursively using the same
`Control` object x.
Using form.Controls.Clear() is not such a good approach because it will clear the entire form and you will even lose all the buttons on the form.
Instead if you just want to clear all the form fields like text fields and radio buttons I would recommend you try the following:
If you have a Reset button “Button1” then on click call a function reset();
In the reset function:
protected void resetButton_Click(object sender, EventArgs e)
{
TextBox1.Text=""; //set equal to empty string to all fields
}
Or redirect to same page by terminating the previous page
protected void resetButton_Click(object sender, EventArgs e)
{
Response.Redirect("~/Test2.aspx", true);
}
For your scenario the easiest way to clear the fields, in my opinion, is to turn off the ViewState (EnableViewState=false) of the controls you want to appear blank after the submit.
Or perhaps for the whole page unless there is some state you need.

ASP:TextBox Value disappears in postback only when password

I have an asp.net textbox like this:
<asp:TextBox ID="PINPad" runat="server" Columns="6" MaxLength="4"
CssClass="PINTextClass"></asp:TextBox>
It is, as you might have guessed, the text box from an on screen PIN pad. Javascript fills in the values. The page is posted back every five seconds (using an update panel if that matters) to update various other unrelated items on the screen. This works just fine.
However, when I convert it to a password text box, like this:
<asp:TextBox ID="PINPad" runat="server" Columns="6" MaxLength="4"
CssClass="PINTextClass" TextMode="Password"></asp:TextBox>
Then whenever the page posts back, the text box is cleared out on the screen and the textbox is empty (though during the timer event, the value does make it back to the server.)
Any suggestions how to fix this, so that it retains its value during postback?
As a security feature, ASP.NET tries to disallow you from sending the password value back to the client. If you're okay with the security issues (i.e. it's either not really secure information or you're sure that the connection is secure), you can manually set the "value" attribute of the control, rather than using its Text property. It might look something like this:
this.PINPad.Attributes.Add("value", this.PINPad.Text);
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
if (!(String.IsNullOrEmpty(txtPwd.Text.Trim())))
{
txtPwd.Attributes["value"]= txtPwd.Text;
}
if (!(String.IsNullOrEmpty(txtConfirmPwd.Text.Trim())))
{
txtConfirmPwd.Attributes["value"] = txtConfirmPwd.Text;
}
}
}
here is another way to do it:-
using System;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebControlLibrary
{
public class PWDTextBox : TextBox
{
public PWDTextBox()
{
this.TextMode = TextBoxMode.Password;
}
public string Password
{
get
{
string val = (string)ViewState["pwd"];
if (string.IsNullOrEmpty(val))
{
return "";
}
else
{
return val;
}
}
set
{
ViewState["pwd"] = value;
}
}
public override string Text
{
get
{
return Password;
}
set
{
Password = value;
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
this.Text = Password;
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Password);
}
}
}
The problem of losing the password in the postback can be avoid making use of Asynchronous JavaScript calls, lets describe a typical scenario for a Login page:
Lets say we have a Login page which allows the user to change the language of its labels when the user choose a language with a dropdownlist
a solution would be to invoke selectedIndexChanged event of the dropdownlist, make a postback which goes to the server and picks up the labels in the chosen language.
in this scenario the field password will be lost due to the security feature of ASP.NET which makes passwords fields not persisted between a postbacks.
This scenario can be solved if the postback is avoided making use of Asynchronous JavaScript Technology and XML (Ajax) calls.
Add a javascript function which will be invoked from the dropdownlist control, in this case this function is assigned to the Command property of the dropdownlist in code behind:
function ValueChanged(div)
{
var table = div.getElementsByTagName("table");
if (table && table.length > 0)
{
var t = table[0].getAttribute('type');
if (t != null && (t == "DropDown"))
{
var inputs = div.getElementsByTagName("input");
if (inputs && inputs.length == 2)
{
{
Translate(inputs[1].value);
}
}
}
}
}
The Translate function takes as parameter the selected option language in the dropdown control and performs the asynchronous call as shown bellow.
function Translate(lang)
{
var request = null;
if (window.XMLHttpRequest)
{
request = new XMLHttpRequest();
if (request.overrideMimeType)
{
request.overrideMimeType('text/xml');
}
}
else if (window.ActiveXObject)
{
request = new ActiveXObject("Msxml2.XMLHTTP");
}
if (request == null)
{
return;
}
var url = "GetLoginTranslations.aspx";
request.open('GET', url +'?lang=' + lang, true);
request.setRequestHeader("Cache-Control", "no-cache");
request.setRequestHeader("Pragma", "no-cache");
request.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
request.onreadystatechange = function () { TranslateLabels(request); };
request.send(null);
}
the function Translate shown above performs the call and get the results in the specified .aspx page (in this case "GetLoginTranslations.aspx")
when the request is completed and the request.onreadystatechange is set to the function TranslateLabels this function will be executed.
on this way the postback is not executed as before in the event onSelectedIndexChanged of the dropdownlist control.
the TranslateLabels function would look something like :
function TranslateLabels(request)
{
if (request.readyState == 4)
{
if (request.status == 200)
{
if (request.responseXML)
{
var objRoot = request.responseXML.documentElement;
if (objRoot)
{
if (objRoot.nodeName == "strings")
{
for (var i = 0; i < objRoot.childNodes.length; i++)
{
var node = objRoot.childNodes[i];
var elem;
switch (node.getAttribute("id"))
{
case "lbl_login":
elem = document.getElementById("lbl_login");
if (elem)
elem.innerHTML = node.firstChild.nodeValue;
break;
}
///....
}
}
}
}
}
}
the request.responseXML contains the XML built in the page GetLoginTranslations.aspx and the structure of this XML is defined there.
the Page_Load() event in the GetLoginTranslations.aspx should look like:
protected void Page_Load(object sender, EventArgs e)
{
if (Request["lang"] != null)
strLang = Request["lang"];
//init response
Response.Clear();
Response.Cache.SetExpires(DateTime.Now);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetValidUntilExpires(true);
Response.ContentType = "application/xml";
Response.Charset = "utf-8";
XmlTextWriter xml = new XmlTextWriter(Response.OutputStream, System.Text.Encoding.UTF8)
{
Formatting = Formatting.None
};
xml.WriteStartDocument();
xml.WriteStartElement("strings");
xml.WriteStartElement("string");
xml.WriteAttributeString("id", "lbl_login");
xml.WriteString(GetTranslation("label_login", strLang));
xml.WriteEndElement();
// ... the other labels
xml.WriteEndElement(); //</strings>
xml.Close();
}
Some other considerations:
set the the property AutoPostback of the dropdownlist to false.
Happens both for view-model properties named 'Password' and 'PIN'. You can bypass the behavior by defining those as:
string Password ;
... rather than:
string Password { get; set; }
If you do so, features such the 'LabelFor' macro displaying 'DisplayAttribute.Name' no longer works, so you'd have to define those directly in the HTML.
Or you can simply name the fields something other than 'Password' or 'PIN'.

Programatic Access to DragHandleTemplate in ASP.NET AJAX ReorderList

Is there a way to programatically access the DragHandleTemplate of a ReorderList (ASP.NET AJAX Control Toolkit) ... Specifically during ItemDataBound for the ReorderList, in order to change its appearance at the per item level?
You can also express FindControlRecursive in LINQ:
private Control FindControlRecursive(Control root, string id)
{
return root.ID == id
? root
: (root.Controls.Cast<Control>().Select(c => FindControlRecursive(c, id)))
.FirstOrDefault(t => t != null);
}
Unfortunately there is no way of getting drag holder from ReorderListItem. Instead, you can create a server control inside DragHandleTemplate (e.g. PlaceHolder) and then find it in your ItemDataBound event handler:
In aspx file:
<DragHandleTemplate>
<div class="dragHandle">
<asp:Label ID="lblDragHandle" runat="server" />
</div>
</DragHandleTemplate>
In aspx.cs file:
protected void ReorderList1_ItemDataBound(object sender, AjaxControlToolkit.ReorderListItemEventArgs e)
{
Label lblDragHandle = (Label)FindControlRecursive(e.Item, "lblDragHandle");
lblDragHandle.Text = e.Item.ItemIndex.ToString();
}
private Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}
I copied FindControlRecursive method from Jeff's blog.
You can not access DragHandleTemplate programatically on the server, but if you create the surrounding elements with unique ID's (per row) you should be able the use CSS-selectors or Javascript to only change some of the items.

Resources