Access other properties of selected Listbox item - c#

I have searched and searched for an answer to this problem. I thought I came close by finding this post:
Get object information of selected listbox item
But I keep getting a an "invalid cast exception" error at this part in the code:
string m = ((Customer)LBox.SelectedItem).ID;
Here is most of my code thus far, where I add the listbox items from a Dataclass (linq to SQL). Where I am stuck is that I'd like to get the DB_ID of the record that I have selected in the Listbox.
I have a workaround where I can do another SQL query on the DB with the customer's name that is the LBox.SelectedItem value, but i figure I must be doing something wrong to not be able to cast the SelectedItem value back to Customer to get the ID?
I am just starting out in C# and know practically nothing, so any help would be much appreciated.
DataClasses1DataContext dc = new DataClasses1DataContext(Properties.Settings.Default.DBConnectionString);
public MainWindow()
{
InitializeComponent();
var q = from accts in dc.Customers where accts.SysStatus == "Active" orderby accts.Customer select accts;
if (dc.DatabaseExists())
foreach (Customer c in q)
LBox.Items.Add(c.Customer);
}
public void LBox_SelectionChanged (object sender, SelectionChangedEventArgs e)
{
lblComp.Content = LBox.SelectedItem;
string m = ((Customer)LBox.SelectedItem).ID;
}
I think #Boxed help me out here.
I modified the code as follows:
foreach (Surgeon c in q)
LBox.Items.Add(c);
LBox.DisplayMemberPath = "Customer";
Then I was able to obtain the values from the Customers Class as such:
string m = ((Customers)LBox.SelectedItem).ID;
lblComp.Content = ((Customers)LBox.SelectedItem).Customer;
txtDetails.Text = m;
Is this code ideal, or should I be doing something else?

Related

Issues with ListView here in C#

So I'm working on learning LINQ and was assigned to work with two .txt files and to join them.
So far I'm doing well, but I've reached a bit of an impasse with the display. I'm supposed to have the name display once and then the following cases that are closed have only the case information.
The issue I'm having is that the name keeps repeating after the dataset is listed in the ListView. I think there is something wrong with the LINQ statement or the way I'm going through the foreach loop. Here is the code for the main form below:
//Fills the lists by calling the methods from the DB classes
techs = TechnicianDB.GetTechnicians();
incidents = IncidentDB.GetIncidents();
//Creates a variable to use in the LINQ statements
var ClosedCases = from Incident in incidents
join Technician in techs
on Incident.TechID equals Technician.TechID
where Incident.DateClosed!= null
orderby Technician.Name, Incident.DateOpened descending
select new { Technician.Name, Incident.ProductCode, Incident.DateOpened, Incident.DateClosed, Incident.Title };
//variables to hold the technician name, and the integer to increment the listview
string techName = "";
int i = 0;
//foreach loop to pull the fields out of the lists and to display them in the required areas in the listview box
foreach (var Incident in ClosedCases)
{
foreach (var Technician in ClosedCases)
{
if (Technician.Name != techName)
{
lvClosedCases.Items.Add(Technician.Name);
techName = Technician.Name;
}
else
{
lvClosedCases.Items.Add("");
}
}
lvClosedCases.Items[i].SubItems.Add(Incident.ProductCode);
lvClosedCases.Items[i].SubItems.Add(Incident.DateOpened.ToString());
lvClosedCases.Items[i].SubItems.Add(Incident.DateClosed.ToString());
lvClosedCases.Items[i].SubItems.Add(Incident.Title);
i++;
}
And here is the result I get: Result
As can be seen by the bar on the right hand side, the list continues on for several more columns.
What am I missing here?
Thank you.
EDIT: Per request, here is what the results are supposed to look like:
The example I was given
Why you are iterating closed cases twice?
foreach (var Incident in ClosedCases)
{
foreach (var Technician in ClosedCases)
{
}
}

Combobox - initial value is right any call after that is giving an error during casting

I am trying to get the guid value of a combobox.
Here be my code:
private void PopulateComboBox()
{
using (var ent = new SuburbanPortalEntities())
{
var qry = (from x in ent.Corporations
select x).ToList();
comboBox_CompanyId.DataSource = qry;
comboBox_CompanyId.DisplayMember = "CompanyCode";
comboBox_CompanyId.ValueMember = "CorporationId";
}
}
And I'm referencing it here:
private void comboBox_CompanyId_SelectedIndexChanged(object sender, EventArgs e)
{
using (var ent = new SuburbanPortalEntities())
{
var corpid = ((Corporation) comboBox_CompanyId.SelectedValue).CorporationId;
// ^^ this is where the exception occurs
//var corpid = (Guid) comboBox_CompanyId.SelectedValue;
// ^^ tried this but the form initialization gives an exception
if (corpid == Guid.Empty) return;
var qry = (from x in ent.Trucks
where x.CorporationId == corpid
orderby x.TruckNumber
select x).ToList();
if (!qry.Any()) return;
comboBox_TruckNumber.DataSource = qry;
comboBox_TruckNumber.DisplayMember = "TruckNumber";
comboBox_TruckNumber.ValueMember = "TruckId";
}
The first time I get the corpid, during the form initialization, it works fine. When I change the value in the combobox, it gives me this error:
Unable to cast object of type 'System.Guid' to type
TruckTransactions.data.Corporation'.
I'm not sure I understand why the type in my combobox is changing.
Here, you populate comboBox_CompanyId with Corporations:
comboBox_CompanyId.DataSource = qry;
comboBox_CompanyId.DisplayMember = "CompanyCode";
Here, you tell it to use the CorporationId property of the selected Corporation (a Guid) as the SelectedValue:
comboBox_CompanyId.ValueMember = "CorporationId";
Here, you take the SelectedValue, which you insisted must be a Guid, and you cast it to Corporation instead, with predictable results:
var corpid = ((Corporation) comboBox_CompanyId.SelectedValue).CorporationId;
Now, the way you could have diagnosed this was to put in a breakpoint and hover the mouse over comboBox_CompanyId.SelectedValue in the debugger, instead of asking strangers on the internet what's going on in the code running on your own desktop. Then you would have found that comboBox_CompanyId.SelectedValue was already the CorporationId you want.
tl;dr
var corpId = (Guid)comboBox_CompanyId.SelectedValue;
comboBox_CompanyId.SelectedItem is a Corporation.
Instead of
comboBox_CompanyId.SelectedValue
do
comboBox_CompanyId.SelectedItem
Problem solved.
Here is what happens
// here
var corpid = ((Corporation) comboBox_CompanyId.SelectedValue).CorporationId;
// comboBox_CompanyId.SelectedValue is already corporation id
// because you did this --> comboBox_CompanyId.ValueMember = "CorporationId";
// so you should be able to do
var corpid = (cast type)comboBox_CompanyId.SelectedValue;
// or, do what I said above
On another note, first set DisplayMember and ValueMember. Assign DataSource last - performance

C# Linq: Sequence Contains no elements, while binding large number of records to gridview

I am trying below query to bind data in Gridview using ASP.NET C# and Linq. My database table has around 55K records. I have gridview placed in user control.
private void DisplayData()
{
Search s = new Search();
search.GetAllSearchRequests(int.MaxValue);
Grid.Bind(search.Results);
}
public void GetAllSearchRequests(int count)
{
using (Entities db = new Entities())
{
var db = (from s in db.SomeTable
orderby s.ID descending
select s).Take(count);
var dbList = db.ToList();
}
}
I am facing issue binding this much records. Application is running for 4-5 minutes and then suddenly it shows below error message:
"Sequence contains no elements."
I have tried most possible solutions I found so far on Stackoverflow, but couldn't get through.
I appreciate community's advise.
Also, I am getting access to dbList variable by passing to below method to convert it to my user defined class list.
private void convertToList(List<PLANVORGANG> dbRequests)
{
foreach (var dbRequest in dbRequests)
{
ServiceRequest svcRequest = new ServiceRequest();
ServiceRequestMapper.MapRequestFromDBObject(dbRequest, svcRequest);
Results.Add(svcRequest);
}
}

Accessing multiple CheckedItems as they are checked

I am trying to filter documents based on selected tags in a checkedlistbox -- it is populated with objects of my class Tag -- but am unable to access the items in order to search. I have tried a couple of variations but the method I am using just now is:
private void chlbTags_ItemCheck(object sender, ItemCheckEventArgs e)
{
List<Tag> chosenTags = new List<Tag>();
foreach (object item in chlbTags.CheckedItems)
{
chosenTags.Add((Tag)item);
}
fillDocs(tags: chosenTags);
}
I know it is probably something simple but all I seem to find when I search seems to be related to getting strings back.
EDIT: chosenTags is always null no matter how many tags are checked.
EDIT 2: Thanks to #Jony A damn it... this has been partly sorted. But now I can't check more than one tag without throwing an InvalidCastException.
EDIT 3: How the checked listbox is populated.
public static List<Tag> fillUsed(List<int> docIds = null)
{
List<Tag> used;
if (docIds == null)
{
used = (from t in frmFocus._context.Tags
where t.AllocateDocumentTags.Count > 0
select t).ToList();
}
else
{
used = (from id in docIds
join adt in frmFocus._context.AllocateDocumentTags on
id equals adt.documentId
join t in _tags on adt.tagId equals t.id
select t).ToList();
}
return used;
}
Any help is appreciated, thanks.
This portion works
public void fillDocs(List<Tag> tags = null)
{
lvDownload.Items.Clear();
if (tags != null)
{
docs = docManagement.fillUp(tags: tags);
}
else
{
docs = docManagement.fillUp();
}
}
The code you posted should fail with a NullReferenceException.
You should replace List<Tag> chosenTags = null; with List<Tag> chosenTags = new List<Tag>();
It should be fine then...
Like Jony stated
This code will fail you have to do more than just assign null to the object.. you need to do what they call "NEWING" the object meaining the key word new
I am trying to filter documents based on selected tags in a checkedlistbox -- it is populated with objects of my class Tag -- but am unable to access the items in order to search. I have tried a couple of variations but the method I am using just now is:
this will work if you change it.
private void chlbTags_ItemCheck(object sender, ItemCheckEventArgs e)
{
List<Tag> chosenTags = new List<Tag>();
foreach (object item in chlbTags.CheckedItems)
{
Tag tag = (Tag) item.Tag;
chosenTags.Add(tag);
-- your code chosenTags.Add((Tag)item);
}
fillDocs(tags: chosenTags);
}
Casting has to be done by getting at the string property
// checkBox is CheckBox
string s = checkBox.Tag.ToString();
you can use something like this to test an individual item or items as well if you like

Convert DataTable to LINQ: Unable to query multiple fields

Importing a spreadsheet I have filled a DataTable object with that data and returns expected results.
Attempting to put this into a format I can easily query to search for problem records I have done the following
public void Something(DataTable dt)
{
var data = from row in dt.AsEnumerable()
select row["Order"].ToString();
}
Works as expected giving me a list of orders. However I cannot add other fields to this EnumerableRowCollection. Attempting to add other fields as follows gives me an error
public void Something(DataTable dt)
{
// row["Version"] throws an error on me
var data = from row in dt.AsEnumerable()
select row["Order"].ToString(), row["Version"].ToString();
}
Error: "A local variable named 'row' cannot be declared in this scope because it would give a different meaning to 'row' which is already used in a 'child' scope to donate something else"
I'm thinking I need to alias the column name but I'm having no luck. What am I missing here?
It sounds like you're writing a bad select statement. Try the following:
public void Something(DataTable dt)
{
var data = from row in dt.AsEnumerable()
select new {
Order = row["Order"].ToString(),
Something = row["Something"].ToString(),
Customer = row["Customer"].ToString(),
Address = row["Address"].ToString()
};
}
That will create a new collection of Anonymously Typed objects that you can iterate over and use as needed. Keep in mind, though, that you want be able to return data from the function. If you need that functionality, you need to create a concrete type to use (in place of anonymous types).
I think you should use select new like this query for example:
var q = from o in db.Orders
where o.Products.ProductName.StartsWith("Asset") &&
o.PaymentApproved == true
select new { name = o.Contacts.FirstName + " " +
o.Contacts.LastName,
product = o.Products.ProductName,
version = o.Products.Version +
(o.Products.SubVersion * 0.1)
};
You probably want the following.
var data = from row
in dt.AsEnumerable()
select new { Order = row["Order"].ToString(), Version = row["Version"].ToString() };

Categories

Resources