Listview items and Image list items missmatching - c#

I have created a image grid view using ListView and ImageList.. image names come from database and images are stored in categories folder. I adding images imgList.Images.Add("", Image.FromFile(#"./categories/" + dr["image"]));
but when program runs 1st list view item not set to the correct image, 1stlistviewitem with second image, i think there is a indexing error. is something wrong with my code or any way to solve this?
private void LoadCategories() {
DataTable categories;
con = new Dbfunctions();
con.MysqlQuery("SELECT * FROM categories WHERE online = 1");
categories = con.QueryEx();
//ImageList
ImageList imgList = new ImageList();
//CLEAR listview_Category items
listView_Category.Items.Clear();
//set listview category items as Large icons
listView_Category.View = View.LargeIcon;
//ADD image list into Listview
listView_Category.LargeImageList = imgList;
int i = 0;
//ADD image into imagelist and Listview
foreach(DataRow dr in categories.Rows){
imgList.Images.Add("", Image.FromFile(#"./categories/" + dr["image"]));
ListViewItem category = new ListViewItem();
//bind listview item vwith image list item
category.ImageIndex = i;
//set Category name
category.Text = dr["name"].ToString();
//set font list items styles
category.Font = new System.Drawing.Font("Courier New", 15, System.Drawing.FontStyle.Regular);
category.ForeColor = System.Drawing.Color.FromArgb(252, 119, 123);
//ADD category items into Listview
listView_Category.Items.Add(category);
imgList.ImageSize = new Size(140, 140);
imgList.ColorDepth = ColorDepth.Depth32Bit;
i++;
}
}

Please provide shapes of DB rows. Maybe you have a missmatch in DB so you call not proper index.

Related

ImageList shows only one image

I'm trying to fill a listview with a database, with each row displaying an image retrieved from a path. It works and an image is displayed in the row, but the problem is that the same image shows up for every list item. So it uses the image from the first database entry for all of the entries.
Here is the code retrieving and displaying the images:
DataTable tab = myConn.GetSchema("Tables");
foreach (DataRow row in tab.Rows) {
Console.WriteLine("{0}", row["TABLE_NAME"].ToString());
}
string mySelectQuery = "Select * from staff";
OdbcCommand command = new OdbcCommand(mySelectQuery, myConn);
OdbcDataReader reader = command.ExecuteReader();
ImageList imgList = new ImageList();
while (reader.Read()) {
ListViewItem item = new ListViewItem(reader.GetString(0), 0);
item.SubItems.Add(reader.GetString(1));
item.SubItems.Add(reader.GetString(2));
// gets image from path in db
imgList.Images.Add(Image.FromFile(reader.GetString(3)));
listView1.SmallImageList = imgList;
item.SubItems.Add(reader.GetString(4));
item.ImageIndex = 0;
listView1.Items.AddRange(new ListViewItem[] { item });
}
You're sharing the same imageList object among all of them. You create it before entering the loop, and then on each iteration, you add another image to the end, but you always tell each new listview item to use the first image in the list. Since it's the same list object every time, that's the same first image every time.
You could just create a new image list for each item:
while (reader.Read()) {
// Create a new one each time.
ImageList imgList = new ImageList();
ListViewItem item = new ListViewItem(reader.GetString(0), 0);

C# wpf listview add items

I have problem with creating listview. I am new in C# and wpf too.
I have tried different methods of filling ListView items and I can not solve it, because the input array is NxN dimensions. I found instructions on Bindig but I can not apply them because I can not create an object of that type, because the input array is dynamic.
I can fill header columns but no rows and columns with values. This code works but all values are together in one column.
public void PrintListView(ResultsTable results)
{
System.Windows.Controls.GridView gv = new System.Windows.Controls.GridView();
gv.AllowsColumnReorder = true;
int j=0;
foreach (DataColumn dc in results.Columns)
{
GridViewColumn gvCol = new GridViewColumn();
gvCol.Header = results.Columns[j].ColumnName;
gvCol.Width = 200;
gv.Columns.Add(gvCol);
j++;
}
lbVysledky.View = gv;
foreach (DataRow dr in results.Rows)
{
string[] array1 = new string[1000];
// List<string> zoznam = new List<string>();
// ObservableCollection<string> kolekcia = new ObservableCollection<string>();
int i = 0;
foreach (DataColumn dc in results.Columns)
{
array1[i] = dr[dc].ToString();
// zoznam.Add (dr[dc].ToString());
// kolekcia.Add(dr[dc].ToString());
i++;
}
this.lbVysledky.Items.Add(new ListViewItem { Content = pole[0] + pole[1]});
}
}
Can someone help me? Thanks
It looks like you're trying to populate the ListView by adding rows and columns one at a time. This is not the approach to use when populating a ListView. Instead, you add the ItemsSource (in this case, your results object) and tell the ListView what the DisplayMemberBinding is for each column, and it will display the proper values in each column for each row.
It probably just means modifying your loop where you add columns to the ListView to something like this:
foreach (DataColumn dc in results.Columns)
{
GridViewColumn gvCol = new GridViewColumn();
gvCol.DisplayMemberBinding = new Binding(dc.ColumnName);
gvCol.Header = results.Columns[j].ColumnName;
gvCol.Width = 200;
gv.Columns.Add(gvCol);
j++;
}
lbVysledky.View = gv;
Then just set the ItemsSource of the ListView to your results object like this:
lbVysledky.ItemsSource = results;
Also, as a side note, you don's appear to be using the foreach construct correctly. you're enumerating over each column, but you're keeping your own counter and accessing the column like this:
gvCol.Header = results.Columns[j].ColumnName;
In a foreach loop, you're already enumerating the columns with the dc variable, so you can access the column like this:
gvCol.Header = dc.ColumnName;
and you don't need to manually count the columns (with j).

How to retrieve the name of a Panorama-Item at runtime?

I am programmatically adding items to my Panorama Control called PanoramaCC.
//function to create the panorama items in our view
private void showPanorama(string panoramaName)
{
//create the panorama item and define it
PanoramaItem genItem = new PanoramaItem();
genItem.Height = 265;
genItem.Width = 440;
genItem.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(PanoramaItem_Tap);
genItem.Name = panoramaName;
//create the stackpanel for the panoramaitem
StackPanel genStack = new StackPanel();
genStack.Orientation = System.Windows.Controls.Orientation.Horizontal;
//margin to be done
genStack.Margin = new Thickness(0, -20, 0, 20);
//load the image
Image genImg = new Image();
genImg.Height = 220;
genImg.Width = 400;
genImg.Stretch = System.Windows.Media.Stretch.Fill;
genImg.Margin = new Thickness(20, 5, 20, 5);
string path = "Assets/AppGraphics/CreditCards/" + panoramaName.ToString() + "Front.png";
Uri uriR = new Uri(path, UriKind.Relative);
BitmapImage imgSource = new BitmapImage(uriR);
genImg.Source = imgSource;
//add image into stackpanel
genStack.Children.Add(genImg);
//add stackpanel to the panoramaitem
genItem.Content = genStack;
//add the panoramaitem to the panoramaview
this.PanoramaCC.Items.Add(genItem);
}
The issue I have is that during runtime I want to retrieve the name of the panoramaItem I am currently looking at and do something with it. I've managed to retrieve the name through the tap event for navigation purposes, string name = ((PanoramaItem)sender).Name; but this is a diffrent scenario. I want to retrieve the name and then delete the item with the corresponding name. Pressing a button should delete the currently selected panoramaItem, is what I'm trying to achieve.
You can get the current PanoramaItem by using the SelectedItem property. You don't need to get the name to delete it.
PanoramaItem currentItem = myPanorama.SelectedItem as PanoramaItem;
if(currentItem != null)
{
//if you want the name for other reasons
string name = currentItem.Name;
//Items returns an ItemsCollection object
myPanorama.Items.Remove(currentItem);
}

Filtering a table in C#

I have a database attached to a C# project, with 3 tables Company, Product, and Inventory. Inventory lists CompanyID, ProductID, and Quantity. Combobox1 lists all the companyID. When you select one, I want listview1 to display only the rows in Inventory with that CompanyID.
//binding DB to memorycopy
this.DBContext = new DBEntities();
listView1.ItemsSource = this.SupPartContext.SPs;
GridViewColumn companyIDColumn = new GridViewColumn();
sNumColumn.Width = 90;
sNumColumn.Header = "companyID";
sNumColumn.DisplayMemberBinding = new Binding("COMPANYID");
GridViewColumn ProductIDColumn = new GridViewColumn();
pNumColumn.Width = 90;
pNumColumn.Header = "ProductID";
pNumColumn.DisplayMemberBinding = new Binding("PRODUCTID");
GridViewColumn quantityColumn = new GridViewColumn();
qtyColumn.Width = 90;
qtyColumn.Header = "quantity";
qtyColumn.DisplayMemberBinding = new Binding("QUANTITY");
GridView newGridview = new GridView();
newGridview.Columns.Add(companyIDColumn);
newGridview.Columns.Add(productIDColumn);
newGridview.Columns.Add(quantityColumn);
listView1.View = newGridview;
Any help, even a point in the right direction would be appreciated. Thank you for your time.
If you are wanting the list view to change automatically without writing any code you're probably not going to be able to get that to happen. However, if you rebind the list when the combo box value changes with the following line it will filter the list as you expect.
listView1.ItemsSource = this.SupPartContext.SPs.Where(sp => sp.CompanyID = {get the select company from the row here})

how to add list of class to listboxbox1 and move selected item to listbox2?

I have 2 list boxes. i want to fill id and value to listbox1 from database. Then I want to add selected items to listbox2 and remove items from listbox1.
List<Plan> lstPlan = new List<Plan>();
SqlDataReader rd = null;
try
{
STS_STORE_PROC_SCHEME.GetPlanParameter objInsert = new STS_STORE_PROC_SCHEME.GetPlanParameter();
objInsert.GetPlan_fun(ref rd, ref ds, SqlReturnType.DATASET_sts);
//while (rd.Read())
//{
// lstPlan.Add(new Plan(Convert.ToInt32(rd[0].ToString()), rd[1].ToString()));
//}
//for (int i = 0; i < lstPlan.Count; i++)
//{
// listBox1.Items.Add(lstPlan[i].ToString());
// //from.Items.Remove(items[i]);
//}
listBox1.DataSource = ds.Tables[0].DefaultView;
listBox1.DisplayMember = "Planname";
listBox1.ValueMember = "nvcharPlanName";
}
catch (Exception ex)
{
}
Its giving error
Items collection cannot be modified when the DataSource property is
set.
I guess you ll need to modify the data that backs the listbox (ds.Tables[0]) and rebind it to the listbox like you do at the line:
listBox1.DataSource = ds.Tables[0].DefaultView;
Similarly, for adding and removing from one listbox to another, simply, you can
define two lists
make your manipulations on these lists (add items from one another,
remove..etc)
set these lists as the DataSource s of the individual listboxes
EDIT:
Code snippet..
Dictionary<int, Plan> dicPlan1 = new Dictionary<int, Plan>();
dicPlan1.Add(1, new Plan());
dicPlan1.Add(2, new Plan());
dicPlan1.Add(3, new Plan());
dicPlan1.Add(4, new Plan());
listbox1.DataSource = new List<Plan>(dicPlan1.Values); //this will get you only the plans
Dictionary<int, Plan> dicPlan2 = new Dictionary<int, Plan>();
dicPlan2.Add(1, new Plan());
dicPlan2.Add(2, new Plan());
dicPlan2.Add(3, new Plan());
dicPlan2.Add(4, new Plan());
listbox2.DataSource = new List<Plan>(dicPlan2.Values); //this will get you only the plans
Then if you want to add from 1st collection to the 2nd collection:
dicPlan2.Add(dicPlan1[1]);
Remove from a collection using the index
dicPlan1.RemoveAt(0); // removes the first item!! (not this => dicPlan2.Add(1, new Plan());)
Simple as that.. donT forget. In order to see the updates in your listboxes, you need to set the datasource again after changing the lists.
listbox1.DataSource = new List<Plan>(dicPlan1.Values);
listbox2.DataSource = new List<Plan>(dicPlan2.Values);
Hope it helps.

Categories

Resources