I have two dropdownlist controls on an add/edit form page, one for countries (called CountryCode) and one for regions/states (called ProvinceCode). The code has been set up so that, when users select "United States" from the country dropdownlist, then the region dropdownlist is populated with all valid US states. If the user selects "Canada" from the country dropdownlist, then the region dropdownlist is populated with valid provinces. This functionality works fine, but when "Canada" is selected, for some reason, the region dropdownlist's value is never saved to the database. I am not sure why this is, especially since I can save US states just fine.
This is the code that is meant to populate the country and region dropdownlists:
protected void Page_Init(object sender, EventArgs e)
{
CountryCode.DataSource = CountryDataSource.LoadAll("Name");
CountryCode.DataBind();
InitCountryAndProvince();
}
private void InitCountryAndProvince()
{
//MAKE SURE THE CORRECT ADDRESS IS SELECTED
Address address = this.Address;
bool foundCountry = false;
if (!string.IsNullOrEmpty(address.CountryCode))
{
ListItem selectedCountry = CountryCode.Items.FindByValue(address.CountryCode);
if (selectedCountry != null)
{
CountryCode.SelectedIndex = CountryCode.Items.IndexOf(selectedCountry);
foundCountry = true;
}
}
if (!foundCountry)
{
Warehouse defaultWarehouse = AbleContext.Current.Store.DefaultWarehouse;
ListItem selectedCountry = CountryCode.Items.FindByValue(defaultWarehouse.CountryCode);
if (selectedCountry != null) CountryCode.SelectedIndex = CountryCode.Items.IndexOf(selectedCountry);
}
//MAKE SURE THE PROVINCE LIST IS CORRECT FOR THE COUNTRY
UpdateCountry();
//NOW LOOK FOR THE PROVINCE TO SET
ListItem selectedProvince = ProvinceCode.Items.FindByValue(address.Province);
if (selectedProvince != null) ProvinceCode.SelectedIndex = ProvinceCode.Items.IndexOf(selectedProvince);
}
private void UpdateCountry()
{
//SEE WHETHER POSTAL CODE IS REQUIRED
string[] countries = AbleContext.Current.Store.Settings.PostalCodeCountries.Split(",".ToCharArray());
//PostalCodeRequired.Enabled = (Array.IndexOf(countries, Country.SelectedValue) > -1);
//SEE WHETHER PROVINCE LIST IS DEFINED
IList<Province> provinces = ProvinceDataSource.LoadForCountry(CountryCode.SelectedValue);
if (provinces.Count > 0)
{
IEnumerable<Province> sortedProvinces = provinces.OrderBy(f => f.Name);
provinces = sortedProvinces.ToList();
ProvinceCode.Visible = false;
ProvinceCode.Visible = true;
ProvinceCode.Items.Clear();
ProvinceCode.Items.Add(string.Empty);
foreach (Province province in provinces)
{
string provinceValue = (!string.IsNullOrEmpty(province.ProvinceCode) ? province.ProvinceCode : province.Name);
ProvinceCode.Items.Add(new ListItem(province.Name, provinceValue));
}
ListItem selectedProvince = FindSelectedProvince();
if (selectedProvince != null) selectedProvince.Selected = true;
ProvinceCode.Enabled = true;
ProvinceCode.Text = string.Empty;
}
else
{
ProvinceCode.Visible = true;
ProvinceCode.Visible = false;
ProvinceCode.Items.Clear();
//Province2Required.Enabled = false;
}
}
private ListItem FindSelectedProvince()
{
string defaultValue = ProvinceCode.Text;
if (string.IsNullOrEmpty(defaultValue)) defaultValue = Request.Form[ProvinceCode.UniqueID];
if (string.IsNullOrEmpty(defaultValue)) return null;
defaultValue = defaultValue.ToUpperInvariant();
foreach (ListItem item in ProvinceCode.Items)
{
string itemText = item.Text.ToUpperInvariant();
string itemValue = item.Value.ToUpperInvariant();
if (itemText == defaultValue || itemValue == defaultValue) return item;
}
return null;
}
protected void Country_Changed(object sender, EventArgs e)
{
//UPDATE THE FORM FOR THE NEW COUNTRY
UpdateCountry();
}
This is the section of the save method that contains the country and region dropdownlist controls:
private void SaveCustomerInfo(int CustID)
{
int currentUserID = AbleContext.Current.UserId;
string editQuery = "UPDATE Customers SET BillToRegion = #BillToRegion, BillToCountry = #BillToCountry WHERE CustomerID = #CustomerID";
string addQuery = "INSERT INTO Customers (BillToRegion, BillToCountry) VALUES(#BillToRegion, #BillToCountry)";
try
{
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
{
cn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.Parameters.Add(new SqlParameter("#BillToRegion", ProvinceCode.SelectedValue));
cmd.Parameters.Add(new SqlParameter("#BillToCountry", CountryCode.SelectedValue));
cmd.ExecuteNonQuery();
cn.Close();
}
}
catch (Exception exception)
{
Logger.Warn("Admin\\People\\Customers\\EditCustomer.aspx - SaveCustomerInfo", exception);
}
And this is the code that is called when the page loads to populate fields with values from the database (if the user is editing an existing entry):
protected void Page_Load(object sender, EventArgs e)
{
_CustomerID = AlwaysConvert.ToInt(Request.QueryString["CustomerID"]);
int.TryParse(Request.QueryString["CustomerID"], out _CustomerID);
if (_CustomerID == 0)
{
AddBtn.Visible = true;
EditBtn.Visible = false;
}
else
{
custIDHidden.Value = _CustomerID.ToString();
AddBtn.Visible = false;
EditBtn.Visible = true;
}
if (!Page.IsPostBack)
{
if (_CustomerID != 0)
{
string selectQuery = "BillToRegion, BillToCountry FROM Customers WHERE CustomerID = #CustomerID";
try
{
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
{
cn.Open();
SqlCommand cmd = new SqlCommand(selectQuery, cn);
cmd.Parameters.Add(new SqlParameter("#CustomerID", custIDHidden.Value));
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
ProvinceCode.SelectedValue = reader["BillToRegion"].ToString();
CountryCode.SelectedValue = reader["BillToCountry"].ToString();
}
}
cn.Close();
}
}
catch (Exception x)
{
Logger.Warn("Admin\\People\\Customers\\EditCustomer.aspx - Page_Load", x);
}
}
}
}
Related
here i want to append the product id of new product in the cookie name cart so can anyone help me with it
protected void lnkAddToCart_Click(object sender, EventArgs e)
{
HttpCookie CartCookie=Request.Cookies["cart"];
if (CartCookie != null)
{
string str = CartCookie.ToString();
str= str + ";"+ _ProductID.ToString();
Response.Cookies["cart"].Value = str;
}
else
{
CartCookie = new HttpCookie("cart");
CartCookie["Cart"] = _ProductID.ToString();
CartCookie.Expires = DateTime.Now.AddYears(1);
Response.Cookies.Add(CartCookie);
}
}
To Set Cookie
public void AddToCartCookie(List<string> listCookie)
{
string objCartListString = string.Join(",", listCookie);
if (Request.Cookies["CartCookie"] == null)
Response.Cookies["CartCookie"].Value = objCartListString;
else
Response.Cookies["CartCookie"].Value = Request.Cookies["CartCookie"].Value + "|" + objCartListString;
Response.Cookies["CartCookie"].Expires = DateTime.Now.AddYears(30);
}
Here listCookie is list of string like
string productName, quantity, price etc;
Then retrieve it by splitting like
if (Request.Cookies["CartCookie"] != null)
{
string objCartListString = Request.Cookies["CartCookie"].Value.ToString();
string[] objCartListStringSplit = objCartListString.Split('|');
foreach(string s in objCartListStringSplit)
{
string[] ss = s.Split(',');
productName = ss[0];
quantity = Convert.ToDouble(ss[1]);
price = Convert.ToDecimal(ss[3]);
.........
}
}
I can't update ComboBox that is linked to another ComboBox. I have one ComboBox that has countries and the other has cities. When I select a country, cityComboBox shows me the cities inside it, but when I change Country it still shows me the same cities. Here is my code
//method to get the cities
public IEnumerable<Ciudad> GetCP(int a) {
string SelectCP = "SELECT [ciudadID],[nombre] FROM [proyectoZoo].[dbo].[Ciudad] where [paisID]=" + a + "";
List<Ciudad> Ciudades = new List<Ciudad>();
foreach (IDataReader reader in this.Execute(SelectCP)) {
Ciudad ciudad = new Ciudad();
ciudad.ciudadID = reader.GetInt32(0);
ciudad.nombre = reader.GetString(1);
Ciudades.Add(ciudad);
}
return Ciudades;
}
Windows form:
IEnumerable<Country> Countries = server.GetCountries();
cmbPais.DataSource = Countries;
IEnumerable<Ciudad> Ciudades = server.GetCP((int)cmbPais.SelectedValue);
cmbCiudad.DataSource = Ciudades;
You need to add this code for the SelectedIndexChanged event handler of cmbPais
void cmbPais_SelectedIndexChanged(object sender, EventArgs e)
{
if(cmbPais.SelectedValue != null)
{
IEnumerable<Ciudad> Ciudades = server.GetCP((int)cmbPais.SelectedValue);
cmbCiudad.DataSource = Ciudades;
}
}
I have a dropdown list and I populate it programmatically with a dataset pulled from a database.
What I like to do is add an option to act like a button " " button. when it is clicked a user is navigated to a different form.
something like this
(screenshot before clicking on the drop-down menu)
(screenshot to show the option like a button " "
This is the code that I am using to populate the menu
private void InventoryAdd_Load(object sender, EventArgs e)
{
InputDepartment.Items.Clear();
InputVendors.Items.Clear();
//populate the Departments menu
dbConnetion db = new dbConnetion();
string sql = " SELECT departmentName, departmentID "
+ " FROM departments "
+ " WHERE status = 'active' ";
InputDepartment.Items.Clear();
var deptSource = new List<ComboItem>();
deptSource.Add(new ComboItem { ID = -1, Text = "Select a Department" });
deptSource.Add(new ComboItem { ID = 0, Text = " < Add New> " });
foreach (var item in db.getData(sql, null, r => new ComboItem()
{
ID = Convert.ToInt32(r["departmentID"]),
Text = r["departmentName"].ToString()
})
)
{
deptSource.Add(item);
};
InputDepartment.DataSource = deptSource;
}
//This generic class will help setting an id and a text for a comboItem
class ComboItem
{
public int ID { get; set; }
public string Text { get; set; }
public string Val1 { get; set; }
public override string ToString()
{
return Text;
}
}
This is my getData Method
// query the data base
public IEnumerable<T> getData<T>(string query, List<MySqlParameter> pars, Func<IDataRecord, T> transform)
{
using (var conn = new MySqlConnection(conn_string))
using (var cmd = new MySqlCommand(query, conn))
{
if (pars != null)
{
foreach (MySqlParameter p in pars)
{
cmd.Parameters.Add(p);
}
}
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return transform(rdr);
}
}
conn.Close();
}
}
Instead of
deptSource.Add(new ComboItem { ID = i.ID, Text = i.Text });
use
deptSource.Add(i);
as i already is a ComboItem. Also, if your getData returns IEnumerable, that might be costly, so use.
foreach (var i in db.getData(sql, null, r => new ComboItem()
{
ID = Convert.ToInt32(r["departmentID"]),
Text = r["departmentName"].ToString()
}).ToList()
or even simpler:
deptSource.AddRange( db.getData(sql, null, r => new ComboItem()
{
ID = Convert.ToInt32(r["departmentID"]),
Text = r["departmentName"].ToString()
}) );
Finally, you need to hook up an event to:
protected override void OnSelectedValueChanged( EventArgs e )
Then you can check if the new value is 0 and perform your new item addition elsewhere.
UPDATE
I don't believe the standard ComboBox supports adding a button. There are 3rd party tools, which do. WPF also does.
I am trying to get the items stored in a sessions variable into a repeater for users to see. However, I am not entirely sure how to do it (I'm new to session variables). Basically, when users enter in quantities for items on once page the hit submit, they are taken to an "order summary" page, which will display what they plan to purchase. I have successfully set up a session variable to contain the sku and quantity of each product the user selects, but I do not know how to get the information out.
I've stored the information in the session variable as [sku],[quantity];[sku],[quantity];[sku],[quantity] and so on. I figure I must do a split or something based on the commas and semicolons but I am not sure how to do so with a session variable.
The code for the product listing page that contains the information to be stored in the session variable:
public partial class GojoptproductlistSublayout : System.Web.UI.UserControl
{
private void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
Item CurrentItem = Sitecore.Context.Item;
Item HomeItem = ScHelper.FindAncestor(CurrentItem, "gojoMarket");
if (HomeItem != null)
{
Item ProductGroup = HomeItem.Axes.SelectSingleItem(#"child::*[##templatename='gojoMarketOfficeBuildigProductMap']/*[##templatename='gojoProductList']");
if (ProductGroup != null)
{
Item[] LocationList = ProductGroup.Axes.SelectItems(#"child::*[##templatename='gojoProductLocation' and #Active = '1']");
if (LocationList != null)
{
DataSet ds = new DataSet();
DataTable locations = ds.Tables.Add("locations");
locations.Columns.Add("LocationName", Type.GetType("System.String"));
locations.Columns.Add("LocationID", Type.GetType("System.String"));
foreach (Item LocationItem in LocationList)
{
DataRow dr = locations.NewRow();
dr["LocationName"] = LocationItem.Fields["Header"].Value;
dr["LocationID"] = LocationItem.ID.ToString();
locations.Rows.Add(dr);
}
locationRepeater.DataSource = ds;
locationRepeater.DataMember = "locations";
locationRepeater.DataBind();
}
}
}
}
}
protected void SetInner(object sender, RepeaterItemEventArgs e)
{
if ((e.Item.ItemType != ListItemType.Footer) & (e.Item.ItemType != ListItemType.Header))
{
Label refID = (Label)e.Item.FindControl("refID");
Label test = (Label)e.Item.FindControl("test");
Repeater areaRepeater = (Repeater)e.Item.FindControl("areaRepeater");
Database db = Sitecore.Context.Database;
Item LocationAreaItem = db.Items[refID.Text];
if (LocationAreaItem != null)
{
Item[] AreaList = LocationAreaItem.Axes.SelectItems(#"child::*[##templatename='gojoProductLocationArea' and #Active = '1']");
if (AreaList != null)
{
DataSet dset = new DataSet();
DataTable areas = dset.Tables.Add("areas");
areas.Columns.Add("AreaName", Type.GetType("System.String"));
areas.Columns.Add("Sku", Type.GetType("System.String"));
areas.Columns.Add("ProductName", Type.GetType("System.String"));
areas.Columns.Add("masterSku", Type.GetType("System.String"));
areas.Columns.Add("masterName", Type.GetType("System.String"));
areas.Columns.Add("Size", Type.GetType("System.String"));
areas.Columns.Add("SkuID", Type.GetType("System.String"));
areas.Columns.Add("AreaID",Type.GetType("System.String"));
areas.Columns.Add("productID", Type.GetType("System.String"));
foreach (Item AreaItem in AreaList)
{
DataRow drow = areas.NewRow();
drow["AreaName"] = AreaItem.Fields["Header"].Value;
drow["AreaID"] = AreaItem.ID.ToString();
areas.Rows.Add(drow);
Item[] SkuList = AreaItem.Axes.SelectItems(#"child::*[(##templatename='gojoPTRefill' or ##templatename = 'gojoPTAccessories' or ##templatename = 'gojoPTDispenser' or ##templatename = 'gojoPTSelfDispensed') and #Active = '1']");
foreach (Item ChildItem in SkuList)
{
Item MarketProduct = db.Items[ChildItem.Fields["Reference SKU"].Value];
drow["productID"] = ChildItem.ID.ToString();
if (MarketProduct != null)
{
Item MasterProduct = db.Items[MarketProduct.Fields["Master Product"].Value];
if (MasterProduct != null)
{
DataRow newRow = areas.NewRow();
if(MasterProduct.TemplateName == "gojoSKUSelfDispensed" || MasterProduct.TemplateName == "gojoSKURefill")
{
newRow["Size"] = MasterProduct.Fields["Size"].Value;
}
else
{
newRow["Size"] = "-";
}
newRow["Sku"] = MasterProduct.Fields["SKU"].Value;
newRow["productID"] = MasterProduct.ID.ToString();
Item MasterProductName = db.Items[MasterProduct.Fields["Complete Product Name"].Value];
if (MasterProductName != null)
{
newRow["ProductName"] = MasterProductName.Fields["Complete Name"].Value;
}
areas.Rows.Add(newRow);
}
}
}
}
areaRepeater.DataSource = dset;
areaRepeater.DataMember = "areas";
areaRepeater.DataBind();
}
}
}
}
protected bool checkQtys(ref int ItemCnt, ref ArrayList LinesToOrder)
{
Repeater locationRepeater = (Repeater)FindControl("locationRepeater");
bool validQtys = true;
string productID = "";
int qty;
qtyErrorMsg.Text = "";
qtyErrorMsgTop.Text = "";
foreach (RepeaterItem repItem in locationRepeater.Items)
{
if (repItem != null)
{
Repeater areaRepeater = (Repeater)repItem.FindControl("areaRepeater");
if (areaRepeater != null)
{
foreach (RepeaterItem skuItm in areaRepeater.Items)
{
if (skuItm != null)
{
Label SkuID = (Label)skuItm.FindControl("SkuID");
Label qtyID = (Label)skuItm.FindControl("qtyID");
PlaceHolder inner = (PlaceHolder)skuItm.FindControl("ProductTable");
if (inner != null)
{
foreach (Control ct in inner.Controls)
{
if (ct is TextBox)
{
TextBox lineQty = (TextBox)ct;
Label prodID = (Label)inner.FindControl("productID");
if (lineQty.Text != "")
{
try
{
int.Parse(lineQty.Text);
productID = prodID.Text;
qty = int.Parse(lineQty.Text);
if (qty > 0)
{
noItemMsg.Visible = false;
noItemMsgTop.Visible = false;
ItemCnt++; //only count items with valid qty values
LinesToOrder.Add(new LineItem(productID, qty));
}
else
{//Qty is 0 or less error
validQtys = false;
qtyErrorMsg.Text = "Quantity must be a number<br />";
qtyErrorMsgTop.Text = "Quantity must be a number<br />";
}
}
catch
{//NaN - display error msg
validQtys = false;
qtyErrorMsg.Text = "Quantity must be a number<br />";
qtyErrorMsgTop.Text = "Quantity must be a number<br />";
}
}
}
}
}
}
}
}
}
}
return validQtys;
}
class LineItem
{//This class will store the product information
public string SKUID;
public int Qty;
public LineItem(string InSKUID, int InQty)
{
this.SKUID = InSKUID;
this.Qty = InQty;
}
}
protected void orderSubmit(object sender, EventArgs e)
{
int ItemCnt = 0;
bool validQtys = true;
ArrayList LinesToOrder = new ArrayList();
Label lb = FindControl("order") as Label;
if (checkQtys(ref ItemCnt,ref LinesToOrder))
{
if (ItemCnt == 0)
{//make sure at least one item with proper qty amount is entered before submitting the order
validQtys = false;
noItemMsg.Visible = true;
noItemMsg.Text = "You must order at least one item<br />";
noItemMsgTop.Visible = true;
noItemMsgTop.Text = "You must order at least one item<br />";
}
if (validQtys)
{//save the information to a session variable and send users to order review page
try
{
foreach (LineItem WorkLine in LinesToOrder)
{
lb.Text += WorkLine.SKUID + ", " + WorkLine.Qty + ";";
}
Session["orderComplete"] = lb.Text;
}
catch (Exception x)
{
Response.Write(x.Message.ToString());
}
Response.Redirect("/united-states/market/office-buildings/obproductmap/OrderReview");
}
}
}
}
Here is the designer code with the repeater that is meant to hold the order summary:
<asp:Repeater ID="orderRepeater" runat="server" >
<headertemplate>
<tr>
<th>SKU</th>
<th>Quantity</th>
</tr>
</headertemplate>
<itemtemplate>
<tr>
<td><%#Eval("sku") %></td>
<td><%#Eval("qty") %></td>
</tr>
</itemtemplate>
</asp:Repeater>
And here is the code behind:
private void Page_Load(object sender, EventArgs e)
{
Item CurrentItem = Sitecore.Context.Item;
Item HomeItem = ScHelper.FindAncestor(CurrentItem, "gojoMarket");
if (Session["orderComplete"] != "")
{
if (HomeItem != null)
{
Item ProductGroup = HomeItem.Axes.SelectSingleItem(#"child::*[##templatename='gojoMarketOfficeBuildigProductMap']/*[##templatename='gojoOrderReview']");
if (ProductGroup != null)
{
//this is where I am confused on how to proceed
}
}
}
}
Everything is working and I did a Response.Write test on the session variable to make sure it had the correct information and it did.
Thanks in advance!
Before I try to address your question, lets take a look at some basics. A Session can hold an object, not just a string object. I would change:
if (Session["orderComplete"] != "")
to
if (Session["orderComplete"] != null && Session["orderComplete"] != "")
if you don't, and Session["orderComplete"] is null, Session["orderComplete"] != "" will throw an error object not set to an instance of an object
And now to your question. Setting your session variable to [sku],[quantity];[sku],[quantity];[sku],[quantity], is not a good idea. For one, its not object oriented and 2, its not going to bind to any repeater or data source. You should create an object and bind a list of those objects to your control:
pseudo code:
class Program
{
static void Main(string[] args)
{
List<Order> orders = new List<Order>();
orders.Add(new Order { Sku = "ABC", Qty = 10});
}
}
public class Order {
public String Sku { get; set; }
public int Qty { get; set; }
}
Then you can bind orders to your repeater. For example:
if (Session["orderComplete"] != null && Session["orderComplete"] != ""){
List<Order> orders = Session["orderComplete"] as List<Order>;
myRepeater.DataSource = orders;
myRepeater.DataBind();
}
I have this code retrieving data from a database but my problem is that it only shows the last item on my ListViewItem. Here is the code:
private void patientLvw_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
cmd = new OleDbCommand("SELECT * FROM PATIENTS ORDER BY PATIENTS.PatientNo;", conn);
reader = cmd.ExecuteReader();
while (reader.Read())
{
String patientNo = ""; ;
String lastName = "";
String firstName = "";
String middleInitial = "";
String age = "";
String address = "";
String type = "";
String status = "";
if (!reader.IsDBNull(0))
{
patientNo = reader.GetInt32(0).ToString();
}
if (!reader.IsDBNull(1))
{
lastName = reader.GetString(1);
}
if (!reader.IsDBNull(2))
{
firstName = reader.GetString(2);
}
if (!reader.IsDBNull(3))
{
middleInitial = reader.GetString(3);
}
if (!reader.IsDBNull(4))
{
age = reader.GetInt32(4).ToString();
}
if (!reader.IsDBNull(5))
{
address = reader.GetString(5);
}
if (!reader.IsDBNull(6))
{
type = reader.GetString(6);
}
if (!reader.IsDBNull(7))
{
status = reader.GetBoolean(7).ToString();
}
ListViewItem lvi = new ListViewItem(patientNo);
e.Item.SubItems.Add(lastName);
e.Item.SubItems.Add(firstName);
e.Item.SubItems.Add(middleInitial + ".");
e.Item.SubItems.Add(age);
e.Item.SubItems.Add(address + ".");
e.Item.SubItems.Add(type);
e.Item.SubItems.Add(status);
e.Item = lvi;
}
}
RetreiveVirtualItem is called for each item, and you are looping though every patient every time it is called. You overwrite e.Item each time, so each item ends up with the last set of values.
You need to check e.ItemIndex and only retrieve the data for that particular row.
Or maybe you don't actually want to use virtual mode, and you should just do the query once on startup and manually add them all to the list.
Answer from before question was edited:
Also, why are you creating two ListViewItems? I think your code should be this:
e.Item = new ListViewItem(patientNo);
if (status.Equals("Yes"))
{
e.Item.ForeColor = Color.Red;
}
e.Item.SubItems.Add(lastName);
e.Item.SubItems.Add(firstName);
e.Item.SubItems.Add(middleInitial + ".");
e.Item.SubItems.Add(age));
e.Item.SubItems.Add(address + ".");
e.Item.SubItems.Add(type);
e.Item.SubItems.Add(status);