ListBox Not displaying values when sorted alphabetically? - c#

This is my sorting logic alphabetic wise
string selectedVal = lstSelectionTags.SelectedValue;
SortedList sortedItems = new SortedList();
for (int i = 0; i < lstSelectionTags.Items.Count; i++)
{
sortedItems.Add(lstSelectionTags.Items[i].Text, lstSelectionTags.Items[i].Value);
}
lstSelectionTags.Items.Clear();
lstSelectionTags.DataSource = sortedItems;
lstSelectionTags.DataTextField = "key";
lstSelectionTags.DataValueField = "value";
lstSelectionTags.DataBind();
when i display items first time in my Listbox by using the below give code
string valueField = Convert.ToString(lstSelectionSub.SelectedItem);
int catID = Convert.ToInt32(lstSelectionSub.SelectedValue);
util = new Utilities();
dt1 = util.GetSubTags_PD(catID, false);
string[] lines = new string[100];
List<string> lines1 = new List<string>();
for (int i = 0; i < dt1.Rows.Count; i++)
{
string s1 = dt1.Rows[i][0].ToString();
if (s1 != "")
{
lines = Regex.Split(s1, ",");
if (!lines1.Contains(lines.ToString()))
{
lines1.AddRange(lines);
}
}
}
lstSelectionTags.DataSource = lines1.Distinct();
lstSelectionTags.DataBind();
It works fine initially and displays the Data but when i do sorting and then try and access the values i don't get any value in the ListBox
EDIT: There seems to be some issue with sorting after sorting the Listbox has a key and value as the DataValue and DataText Field whereas when i rebind it there is no DataValue and DataText Field. Please help.
ISSUE SOLVED : Just used
if (lines1.Count > 0)
{
lstSelectionTags.DataSource = null;
lstSelectionTags.Items.Clear();
lstSelectionTags.DataSource = lines1.Distinct();
lstSelectionTags.DataTextField = null;
lstSelectionTags.DataValueField = null;
lstSelectionTags.DataBind();
}

Related

EPPLUS: Length of a DataValidation list cannot exceed 255 characters

This question is answered on a basic level on another post: here However for my case I am not able to hard code the validation values into the sheet I am pulling them from a database based on the content of the cell and will need to do a separate validation for 4 columns on every row. Is there a way this can be achieved? Thank you in advance.
// Data Validations //
// Product Validation //
for (int i = 2; i < rowCount; i++)
{
var val = ws.DataValidations.AddListValidation(ws.Cells[i, 5].Address);
val.ShowErrorMessage = true;
val.ErrorTitle = "Entry was invalid.";
val.Error = "Please choose options from the drop down only.";
var ticketEntity = ticketQueryable.Where(o => o.TTSTicketNumber == ws.Cells[i, 3].Value.ToString()).Single<CustCurrentTicketEntity>();
var prodIds = prodExtQueryable.Where(p => p.ZoneId == ticketEntity.ZoneId && p.TicketTypeId == ticketEntity.TicketTypeId);
if (ticketEntity != null)
{
var prodIdsList = new List<int>();
foreach (var prodId in prodIds)
{
prodIdsList.Add(prodId.ProductId);
}
var ProductList = ProductCache.Instance.AllProducts.Where(p => prodIdsList.Contains(p.ProductId)).Select(p => new SelectListItem() { Value = p.ProductId.ToString(), Text = p.Name });
foreach (var Result in ProductList)
{
var product = Result.Text;
val.Formula.Values.Add(product);
}
}
}
So yes as Ernie said What I did was add a second sheet "ProductValidations" and set it to Hidden (unhide it to check that it is working). I then Load my data from the DataTable and then add some basic EPPLUS formatting. I then iterate over the Rows and Insert values into the "ProductValidations" sheet for each cell. Next I convert my column number to the correct Excel Column letter name (A, AC, BCE etc) I then create a string to pass back as an Excel formula targeting the correct range of cells in the "ProductValidations" sheet. Also to anyone having an issue downloading the Excel file from the server this guid method works just fine for me.
public ActionResult DownloadExcel(EntityReportModel erModel, string filename)
{
var dataResponse = iEntityViewService.LoadEntityView(new EntityViewInput
{
SecurityContext = SessionCache.Instance.SecurityContext,
EntityViewName = "Ticket",
Parameters = new Dictionary<string, object> {
{"MinTicketDateTime", "04/26/16"}
}
});
var table = dataResponse.DataSet.Tables[0];
filename = "TICKETS-" + DateTime.Now.ToString("yyyy-MM-dd--hh-mm-ss") + ".xlsx";
using (ExcelPackage pack = new ExcelPackage())
{
ExcelWorksheet ws = pack.Workbook.Worksheets.Add(filename);
//Add second sheet to put Validations into
ExcelWorksheet productVal = pack.Workbook.Worksheets.Add("ProductValidations");
// Hide Validation Sheet
productVal.Hidden = OfficeOpenXml.eWorkSheetHidden.Hidden;
// Load the data from the datatable
ws.Cells["A1"].LoadFromDataTable(table, true);
ws.Cells[ws.Dimension.Address].AutoFitColumns();
int columnCount = table.Columns.Count;
int rowCount = table.Rows.Count;
// Format Worksheet//
ws.Row(1).Style.Font.Bold = true;
List<string> deleteColumns = new List<string>() {
"CurrentTicketId",
};
List<string> dateColumns = new List<string>() {
"TicketDateTime",
"Updated",
"InvoiceDate"
};
ExcelRange r;
// Format Dates
for (int i = 1; i <= columnCount; i++)
{
// if cell header value matches a date column
if (dateColumns.Contains(ws.Cells[1, i].Value.ToString()))
{
r = ws.Cells[2, i, rowCount + 1, i];
r.AutoFitColumns();
r.Style.Numberformat.Format = #"mm/dd/yyyy hh:mm";
}
}
// Delete Columns
for (int i = 1; i <= columnCount; i++)
{
// if cell header value matches a delete column
if ((ws.Cells[1, i].Value != null) && deleteColumns.Contains(ws.Cells[1, i].Value.ToString()))
{
ws.DeleteColumn(i);
}
}
int col = 0;
int Prow = 0;
int valRow = 1;
// Data Validations //
// Iterate over the Rows and insert Validations
for (int i = 2; i-2 < rowCount; i++)
{
Prow = 0;
col++;
valRow++;
// Add Validations At this row in column 7 //
var ProdVal = ws.DataValidations.AddListValidation(ws.Cells[valRow, 7].Address);
ProdVal.ShowErrorMessage = true;
ProdVal.ErrorTitle = "Entry was invalid.";
ProdVal.Error = "Please choose options from the drop down only.";
var ticketEntity = ticketQueryable.Where(o => o.TTSTicketNumber == ws.Cells[i, 3].Value.ToString()).Single<CustCurrentTicketEntity>();
// Product Validation //
var prodIds = prodExtQueryable.Where(p => p.ZoneId == ticketEntity.ZoneId && p.TicketTypeId == ticketEntity.TicketTypeId);
if (ticketEntity != null)
{
var prodIdsList = new List<int>();
foreach (var prodId in prodIds)
{
prodIdsList.Add(prodId.ProductId);
}
var ProductList = ProductCache.Instance.AllProducts.Where(p => prodIdsList.Contains(p.ProductId)).Select(p => new SelectListItem() { Value = p.ProductId.ToString(), Text = p.Name });
//For Each Item in the list move the row forward and add that value to the Validation Sheet
foreach (var Result in ProductList)
{
Prow++;
var product = Result.Text;
productVal.Cells[Prow, col].Value = product;
}
// convert column name from a number to the Excel Letters i.e A, AC, BCE//
int dividend = col;
string columnName = String.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
// Pass back to sheeet as an Excel Formula to get around the 255 Char limit for Validations//
string productValidationExcelFormula = "ProductValidations!" + columnName + "1:" + columnName + Prow;
ProdVal.Formula.ExcelFormula = productValidationExcelFormula;
}
}
// Save File //
var fileStream = new MemoryStream(pack.GetAsByteArray());
string handle = Guid.NewGuid().ToString();
fileStream.Position = 0;
TempData[handle] = fileStream.ToArray();
// Note we are returning a filename as well as the handle
return new JsonResult()
{
Data = new { FileGuid = handle, FileName = filename }
};
}
}
[HttpGet]
public virtual ActionResult Download(string fileGuid, string fileName)
{
if (TempData[fileGuid] != null)
{
byte[] data = TempData[fileGuid] as byte[];
return File(data, "application/vnd.ms-excel", fileName);
}
else
{
//Log err
return new EmptyResult();
}
}

ListView does not show first column

I have the method here below. Before this method, I was getting the data from one table and now from two tables so I changed ListView as shown below.
Before using two different tables the ListView was designed at properties tab and all was working good.
The method below when writing items bypass the first column and begins from the second.
What is the bug ?
Any help will be very precious.
private void ShowPage()
{
// some declarations such count,LineNbr etc...
if (PublicVariables.PrintData == 1)
{
// seeting column headers and with and alignement if PrintData=1
newtmp = new string[5];
}
else
{
// seeting column headers and with and alignement if PrintData=2
newtmp = new string[7];
}
LineNbr = File.ReadAllLines(fName).Length;
ppc.View = View.Details;
ListViewItem DispItem = new ListViewItem();
while (counter < LineNbr && (line = streamToPrint.ReadLine()) != null)
{
string[] tmp = line.Split('|'); // Splitting the Data
sayac = 0;
for (int i = 0; i < tmp.Length; ++i)
{
if (tmp[i] != "")
{
newtmp[sayac] = tmp[i];
++sayac;
}
}
for (int a=0; a<newtmp.Length; ++a) // I add to SubItems
DispItem.SubItems.Add(newtmp[a]);
ppc.Items.AddRange(new ListViewItem[] {DispItem}); // I pass to ListView ppc
if (PublicVariables.PrintData == 1) //Initialise newtmp string
newtmp = new string[5];
else
newtmp = new string[7];
DispItem = new ListViewItem(); // Initialiase ListViewItem
++counter;
}
}
for (int a=0; a<newtmp.Length; ++a) // I add to SubItems
DispItem.SubItems.Add(newtmp[a]);
ppc.Items.AddRange(new ListViewItem[] {DispItem}); // I pass to Lis
Instead of those lines above, I have to do as below :(
DispItem = new ListViewItem(newtmp);
ppc.Items.Add(DispItem);
I was trying everything to resolve this.
After all, my excuses for those who give mind

how to represent in datagridview?

I have a class that I did all calculation in it and now I want to represent this data in datagridview what should I do using c#?
that what I did but it didn't work
for (int i = 1; i <= cust_num; i++)
{
dataGridView1.Rows.Add();
dataGridView1.Rows[i].Cells["Customer_Number"].Value = cust_num.ToString();
dataGridView1.Rows[i].Cells["Time_between_Arrival"].Value = inter_Arrival_time.ToString();
dataGridView1.Rows[i].Cells["service_Time"].Value = service_Time.ToString();
dataGridView1.Rows[i].Cells["Arrival_Time"].Value = rand_inter_Arrival.ToString();
dataGridView1.Rows[i].Cells["Time_Service_Beg"].Value = Arrival_Time.ToString();
dataGridView1.Rows[i].Cells["ServiceNum"].Value = service_number.ToString();
dataGridView1.Rows[i].Cells["service_Time"].Value = rand_service_time.ToString();
dataGridView1.Rows[i].Cells["Time_service_End"].Value = finsh_time.ToString();
dataGridView1.Rows[i].Cells["Waiting_Time"].Value = waiting_time.ToString();
// dataGridView1.Rows.Add(row);
}
string[] row = new string[] { cust_num.ToString(), inter_Arrival_time.ToString(), ...... };
dataGridView1.Rows.Add(row);
You can add row to datagridview like this

How to get cell value in GridView (WITHOUT using cell index)

how to get cell value from gridview without using cell index?
Let say the first column name in my table is "RowNumber".
instead of using
string name = GridView1.Rows[0].Cells[0].Text;
Something like
string name = GridView1.Rows[0].Cells["RowNumber"].Text;
You could cast the GridViewRow's DataItem property into a DataRowView, and then reference the column names:
DataRowView rowView = (DataRowView)GridView1.Rows[0].DataItem;
string name = rowView["RowNumber"].ToString();
You can't do this from the Cells collection, because they are just TableCell objects, and they don't know anything about the underlying data.
The DataItem property represents the values in that row from the underlying datasource, so that's what you want to deal with.
You can use datakeys to access any data you want from the row index.
In the markup of the gridview, add all the fields you want to be able to access to the gridview.
<asp:GridView ID="gvTransactionHistory" runat="server"
AutoGenerateColumns="false"
onselectedindexchanging="gvTransactionHistory_SelectedIndexChanging"
DataKeyNames="ID, AnyField">
These datakeys can be accessed in the code behind with the row index
var id = gvTransactionHistory.DataKeys[rowIndex].Values["ID"];
var AnyField = gvTransactionHistory.DataKeys[rowIndex].Values["AnyField"];
here is a function I wrote. since we typically get the same list of fields over and over again, I cached the index lookups.
private static readonly HybridDictionary cache = new HybridDictionary();
public static object[] GetColumnValues(
this GridView g,
int rownumber,
string columnNamesCommaSeparated)
{
var dataView = g.DataSource as DataView;
if (dataView != null)
{
DataRow dataRow = dataView[rownumber].Row;
object[] items = dataRow.ItemArray;
DataColumnCollection columns = dataRow.Table.Columns;
string lookupkey = g.ID + columnNamesCommaSeparated;
var colids = cache[lookupkey] as int[];
int columnCount;
if (colids == null)
{
string[] columnNames = columnNamesCommaSeparated.Split(',');
columnCount = columnNames.Count();
colids = new int[columnCount];
for (int i = 0; i < columnCount; i++)
{
colids[i] = columns.IndexOf(columnNames[i]);
}
cache.Add(lookupkey, colids);
}
columnCount = colids.Length;
var values = new object[columnCount];
for (int i = 0; i < columnCount; i++)
{
values[i] = items[colids[i]] ?? "";
}
return values;
}
return null;
}
to use it do something like
object[] values = g.GetColumnValues(e.Row.DataItemIndex, "Firstname,Lastname,CompanyName");
if (values != null)
{
string header = Server.HtmlEncode(values[0] + " " + values[1] + " # " + values[2]);
}
// do whatever you want with this value

List<> ends up being null; can't seem to .Add properly

I have a GridView with CheckBoxes and I wish to retrieve Cell[1] in every row that was checked. The list always end up being 'null'. The code is below. I added a string to display the output and that works fine. So I'm probably Adding it incorrectly but I don't know what. Any help would be appreciated. Cheers~
List<int> indices = new List<int>();
CheckBox cb = new CheckBox();
string text = "";
foreach (GridViewRow row in GV0.Rows)
{
if (((CheckBox)row.FindControl("CheckBox1")).Checked)
{
text += row.Cells[1].Text;
indices.Add(int.Parse(row.Cells[1].Text));
}
}
Label1.Text = text;
Session["indicesList"] = indices;
Response.Redirect("About.aspx");
The code for the page that is being redirected to:
List<List<string>> all = new List<List<string>>();
List<string> fields = new List<string>();
List<Type> fieldtypes = new List<Type>();
List<int> indices = new List<int>();
int show = 0;
if (!Page.IsPostBack)
{
all = (List<List<string>>)Session["all"];
fields = (List<string>)Session["fields"];
fieldtypes = (List<Type>)Session["fieldtypes"];
indices = (List<int>)Session["indiceslist"];
show = (int)Session["show"];
}
int j = 0;
List<List<string>> dupes = new List<List<string>>();
for (int i = 0; i < show; i++)
{
if (j < indices.Count)
{
if (int.Parse(all[i][0]) == indices[j])
{
dupes.Add(all[i]);
j++;
}
}
}
You're setting your list in the session with a key of indicesList but you're retrieving it with a key of indiceslist (Note the difference in case on the letter "L").
I would suggest creating a property for your list that gets and sets from the session. It makes it much easier to manage.
public List<int> Indices
{
get
{
var val = Session["indicesList"] as List<int>;
if(val == null)
{
val = new List<int>();
Session["indicesList"] = val;
}
return val;
}
set
{
Session["indicesList"] = value;
}
}

Categories