How to sort DevExpress Gallery Control items? - c#

I am using DevExpress GalleryControl in my library program.
But the problem is I want to sort items in GalleryControl and I dont know how can I do that, I believe that GalleryControl doesn't have a built in feature for sorting items(not really sure tho).
So my program is connected in database(SQL).
So here I want to happen, I want to sort it by alphabetically or by author or by department , to do that I want it to create group for gallery control and the group will contains the item that belong to it.
Can you help me with it?
Check for what I've done:
public void LoadBooks(object state)
{
GalleryItemGroup group = new GalleryItemGroup();
galleryControl1.Gallery.Groups.Add(group);
group.Items.Clear();
group.Caption = "All books";
group.CaptionAlignment = GalleryItemGroupCaptionAlignment.Center;
MySqlConnection connection = null;
try
{
connection = new MySqlConnection(MyConnectionString);
connection.Open();
MySqlCommand cmd = connection.CreateCommand();
//This is arrange by alphabetically but I want to create gallery groups for each letters and the group will contain every items that belongs to it.
cmd.CommandText = "Select * from booktable ORDER BY booktitle";
MySqlDataAdapter adap = new MySqlDataAdapter(cmd);
DataTable ds = new DataTable();
adap.Fill(ds);
Invoke(new Action(() =>
{
for (int i = 0; i < ds.Rows.Count; i++)
{
byte[] byteBLOBData = (byte[])ds.Rows[i]["bookphoto"];
var stream = new MemoryStream(byteBLOBData);
Image bookimages = Image.FromStream(stream);
string author = ds.Rows[i]["bookauthor"].ToString();
string title = ds.Rows[i]["booktitle"].ToString();
group.Items.Add(new GalleryItem(bookimages, title, author));
group.Items[i].HoverImage = group.Items[i].Image;
}
}));
}
finally
{
if (connection != null && connection.State == ConnectionState.Open)
{
connection.Close();
}
}
}
By default, it was sorted by book id which is my primary key in SQL.
Please somebody help me , I'll appreciate any help.
By the way I am new here in Stackoverflow. It's nice to be here.

Related

Getting specific column data from database in C#

I have created a search function that returns product data in a DataGridView (data is coming from local database), it does work but I need to have control over returned data in my grid view.
Current behavior
It returns all columns of database row in DataGridView
What I want
Returning only 2 or 3 columns of searched item instead of all columns
Create new list of searched items so I can edit those returned data
Logic
Search for product
Get product name and price from database, add custom quantity field make new list and add this item to show in DataGridView
Be able to change quantity field in DataGridView
Code
Here is my search code that returns all columns of product table
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"].ConnectionString))
{
if (cn.State == ConnectionState.Closed)
cn.Open();
using (DataTable dt = new DataTable("Products"))
{
using (SqlCommand cmd = new SqlCommand("select * from Products where Id=#Id or Name like #Name", cn))
{
cmd.Parameters.AddWithValue("Id", searchBox.Text);
cmd.Parameters.AddWithValue("Name", string.Format("%{0}%", searchBox.Text));
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
// Following line will show all columns of founded product and replace it with next search result
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
selectedItems.DataSource = dt;
}
}
}
PS: Code above finds products based on id or name entered in search field and return all columns of product row.
Idea:
I think I can be able to create my list after finding product but the issue I'm facing is that I'm not sure how to get those specific columns from my dt (table row),
Here is what I've tried and failed (commented)
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"].ConnectionString))
{
if (cn.State == ConnectionState.Closed)
cn.Open();
using (DataTable dt = new DataTable("Products"))
{
using (SqlCommand cmd = new SqlCommand("select * from Products where Id=#Id or Name like #Name", cn))
{
cmd.Parameters.AddWithValue("Id", searchBox.Text);
cmd.Parameters.AddWithValue("Name", string.Format("%{0}%", searchBox.Text));
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
//selectedItems.DataSource = dt; //<-- changed with lines below
List<string> items = new List<string>();
items.Add(dt); // <-- here is the issue (it expect to get string of my table row let say: Price column, but I don't know how to get Price column value from dt)
selectedItems.DataSource = items;
}
}
}
PS: code above is just idea and obviously I am not sure if it is best way to do it or not that's why I'm asking here :)
Any suggestions?
Update
I've created new class and added my data to that class as following
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public string Price { get; set; }
public string Qty { get; set; }
}
Then in my query I added
List<Item> itemList = new List<Item>();
for (int i = 0; i < dt.Rows.Count; i++)
{
Item item = new Item();
item.Id = Convert.ToInt32(dt.Rows[i]["Id"]);
item.Name = dt.Rows[i]["Name"].ToString();
item.Price = dt.Rows[i]["SellPrice"].ToString();
item.Qty = dt.Rows[i]["Qty"].ToString();
itemList.Add(item);
}
selectedItems.DataSource = itemList;
Now it does return data in my selectedItems but when I search for next product instead of adding it to the list it replace it with first product.
According to your sql query you are selecting all columns of the table.
To get the specific columns please change your sql query as such:
SqlCommand cmd = new SqlCommand("select Products.id, Products.name from Products where Id=#Id or Name like #Name", cn);
Thank you.
As per my understanding based on the comments, you are looking for some Linq code.
You only need to convert your result to a list that you could use.
Here is some code that might help you achieve this.
var result = dt.AsEnumerable().Select(x=> new {
Id = x["Id"],
Name = x["Name"],
Quantity = {Your Logic here}
});
selectedItems.DataSource = result;
You can then assign result to your datasource. You did not specify what your datasource is assigned to (selectedItems) so I do not know what type it is. but this should theoretically work. Just remove Quantity = {Your Logic here} from the code and see if it display's after which you could then just add it back and populate what you want Quantity to be
UPDATE
Because selectedItems is a DataGridView it requires a DataTable object to display the data. In which case you can not use an anonymous list as I created you would need something like this.
DataTable dtResult = new DataTable();
dtResult.Columns.Add("Id");
dtResult.Columns.Add("Name");
dtResult.Columns.Add("Quantity");
var result = dt.AsEnumerable().Select(x=> dtResult.Rows.Add(x["Id"],
x["Name"],
{Your Logic for Quantity here}
));
selectedItems.DataSource = result;
If you want to test this solution you can create a console application in c# and do something like where you can see the datasource is correct.
You could refer to the following code to show specific column data from database in winform datagirdview.
private void button1_Click(object sender, EventArgs e)
{
string str = "str";
SqlConnection connection = new SqlConnection(str);
connection.Open();
string sql = "select * from Product where Id=#Id or Name like #Name";
SqlCommand command = new SqlCommand(sql,connection);
command.Parameters.AddWithValue("#Id", textBox1.Text);
command.Parameters.AddWithValue("#Name", string.Format("%{0}%", textBox1.Text));
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable table = new DataTable();
adapter.Fill(table);
var dt = from t in table.AsEnumerable()
select new
{
//Name=t.Field<string>("Name"), //The same way to show other columns data
Price = t.Field<string>("Price")
};
dataGridView1.DataSource = dt.ToList();
}
Result:
Database:

how to create an id to be shown in the text box based on selected dropdownlist

i would like to create an id generator based on their department selected from the dropdownlist. lets say my ddl has 3 departments (A,B,C) and when generating an id it will be A20181001 and then A20181002 upon submission but when i pick B from the ddl after sending A20181001 to the database, it will be B20181001.
so far i have created the code for the increment for the id without the departments. here is the code i did so far. (I used the date for today so the 20181001 is just an example):
void getMRF_No()
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
int mrf = 0;
int i;
string a;
//string x = Request.QueryString["BUnit"];
string mrfNo = "";
database db = new database();
string conn = dbe.BU();
SqlConnection connUser = new SqlConnection(conn);
SqlCommand cmd = connUser.CreateCommand();
SqlDataReader sdr = null;
string query = "SELECT TOP 1 MRF_NO FROM incMRF ORDER BY MRF_NO DESC";
connUser.Open();
cmd.CommandText = query;
sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr.GetInt32(0).ToString();
}
if (mrfNo == "")
{
mrfNo = Convert.ToString(year) + "" + 00;
}
mrf += 0;
i = Convert.ToInt32(mrfNo) + 1;
a = i.ToString();
txtMRFNo.Text = a;
connUser.Close();
}
any help to improve this code will be helpful. thank you :)
EDIT:
here is the dropdown list code:
void SelectBU()
{
string database = dbe.BU ();
using (SqlConnection con = new SqlConnection(database))
{
con.Open();
string query = "select BUnit from BusinessUnit";
using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
{
DataSet ds = new DataSet();
sda.Fill(ds, "BUnit");
ddlBu.DataSource = ds;
ddlBu.DataTextField = "BUnit";
ddlBu.DataValueField = "BUnit";
ddlBu.DataBind();
selectOption(ddlBu, "Select Dept");
}
con.Close();
}
}
EDIT2: I will state what im searching for here incase some doesnt know or understand. What i want is upon selecting a department from a dropdownlist, for example i picked A. the textbox show show A2018102201. if i select B it should show B2018102201 and if its C then c2018102201. and it will change its number once i submit it to a database and a new form loads. So if A2018102201 is already in the database, then the text shown in the text box will be A2018102202. BUT if i select B then the textbox will show B2018102201 since it does not exist in the database yet.
First you should get max ID, then increase the numeric part of your Id, and If this is a multi-user application, you have to lock your table, because it might create many ID duplication, Therefore I'm not recommend to create ID like this on c#, it is better to create a Sequence on SQL server. but I wrote this sample for you, just call it with proper value.
static string getMRF_No(string prefixCharFromDropDownList)
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
string mrfNo = "";
SqlConnection connUser = new SqlConnection("Server=130.185.76.162;Database=StackOverflow;UID=sa;PWD=$1#mssqlICW;connect timeout=10000");
SqlCommand cmd = new SqlCommand(
$"SELECT MAX(MRF_NO) as MaxID FROM incMRF where MRF_NO like '{prefixCharFromDropDownList}%'"
,connUser
);
connUser.Open();
SqlDataReader sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr["MaxID"].ToString();
}
if (mrfNo == "")
{
mrfNo = prefixCharFromDropDownList + year + "000";
}
else
{
mrfNo = prefixCharFromDropDownList + (long.Parse(mrfNo.Substring(1)) + 1).ToString().PadLeft(2);
}
sdr.Close();
cmd = new SqlCommand($"INSERT INTO incMRF (MRF_NO) values ('{mrfNo}')",connUser);
cmd.ExecuteNonQuery();
connUser.Close();
//txtMRFNo.Text = prefixCharFromDropDownList + i.ToString();
return mrfNo;
}
I call this method on a console application as test.
static void Main(string[] args)
{
// send dropdown (selected char) as prefix to method
var newAId = getMRF_No("A");
var newAnotherAId = getMRF_No("A");
var newBId = getMRF_No("B");
var newAnotherAId2 = getMRF_No("A");
Console.ReadKey();
}

Cant display images in Listview from database mysql in c#

I couldn't display the images from my database in Listview although I can retrieve some data like my the title of it.
Check out my code:
public void LoadBooks()
{
MySqlConnection connection = new MySqlConnection(MyConnectionString);
connection.Open();
try
{
listView1.Clear();
ImageList myImageList1 = new ImageList();
myImageList1.ImageSize = new System.Drawing.Size(80, 80);
listView1.LargeImageList = myImageList1;
MySqlCommand cmd = connection.CreateCommand();
cmd.CommandText = "Select * from booktable";
MySqlDataAdapter adap = new MySqlDataAdapter(cmd);
DataTable ds = new DataTable();
adap.Fill(ds);
foreach (DataRow dr in ds.Rows)
{
byte[] byteBLOBData = (byte[])dr["bookphoto"];
var stream = new MemoryStream(byteBLOBData);
Image bookimages= Image.FromStream(stream);
myImageList1.Images.Add(bookimages);
ListViewItem lsvparent = new ListViewItem();
lsvparent.Text = dr["booktitle"].ToString();
listView1.Items.Add(lsvparent);
}
}
catch (Exception)
{
throw;
}
finally
{
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
}
}
Although the size of the image is showing in the Listview but there is any image just a blank image.
Hope you help me . Thank you
I don't see where you set the IamgeIndex that points to the ImageList.
It is a property of the ListViewItem and you can set it when adding it or at any time later on.
This will set it to the latest image in the list:
listView1.Items.Add(lsvparent, myImageList1.Image.Count - 1);
To change it later you can use:
listView1.Items[23].ImageIndex = 42;
or, if you have nice names:
listView1.Items[lsvparent].ImageIndex = 0;
Note that any ImageList is restricted to one Size, a maximum of 256x256 pixels and one bit depth fo all images!
It is a good idea to load a default image as the first one into the ImageList i.e. at index = 0 so you have a common one to fall back to.

Get Data from Mysql Database to array in C# array out of bounds

I connect mysql database, then I get the x row. And when I try to the push the array the system got error. I dont understand this problem.
I tried this code. But I got error like array out of bonds...
int uz = b();// this func. get row number on the table
int[] userData = new int[uz];
MySqlConnection bag = new MySqlConnection(connstring);
MySqlCommand cmd = new MySqlCommand("Select readerid From readers",bag);
bag.Open();
MySqlDataReader oku = cmd.ExecuteReader();
oku.Read();
for (int i = 0; i <= uz; i++) {
userData[i] = Convert.ToInt32(oku[i]);
listBox1.Items.Add(userData[i]);
}
bag.Close();
I think you should use i < uz instead of i <= uz.
for (int i = 0; i < uz; i++)
EDIT:
Based on your comment I think you can try this:
List<int> userData = new List<int>();
MySqlConnection bag = new MySqlConnection(connstring);
MySqlCommand cmd = new MySqlCommand("Select readerid From readers",bag);
bag.Open();
MySqlDataReader oku = cmd.ExecuteReader();
while (oku.Read())
{
int current = Convert.ToInt32(oku["readerid"]);
userData.Add(current);
listBox1.Items.Add(current);
}
Dont forget to close the connections after you dont need them.
It looks like the main problem is that you believed oku[i] would give you data from the row at index i. What it really does is give you data from the column at index i for the current row. However, there were several other issues with the original code as well.
This should point you in a better direction:
var userData = new List<int>();
using (var bag = new MySqlConnection(connstring))
using (var cmd = new MySqlCommand("Select readerid From readers",bag))
{
bag.Open();
using (MySqlDataReader oku = cmd.ExecuteReader())
{
while (oku.Read())
{
userData.Add(oku[0]);
//userData.Add(oku["readerid"]); //would also work
}
}
}

Reading data off SQL Rows sequentially

I am working on a process where I basically need to read a lot of customer data, apply some calculations and processes to the data and then save them elsewhere. I know how to do what I want to do, but what I don't know is how to read the data sequentially (row by row). Right now, I am reading the number of accounts so I can make a loop. Here's what I have:
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Connection"].ConnectionString);
conn.Open();
SqlCommand comm = new SqlCommand("SELECT COUNT(*) FROM Accounts WHERE ID = #ID AND Open = 1", conn);
comm.Parameters.AddWithValue("#ID", Session["ID"]);
Int32 count = (Int32)comm.ExecuteScalar();
//testing purposes
Label3.Text = count.ToString();
int i = 0;
while (i <= count)
{
//READ COMMAND HERE?
i = i + 1;
}
if (i == count)
{
//loading bar
UpdateProgress1.Visible = false;
}
Now Inside the loop (I guess!) I need to execute a code to read data from each row where ID = #ID, read the data, use some processes (i know how to work them) and update the data (also know how to do this). I just need to be able to read the data and I don't know how. Help would be appreciated!
Instead of ExecuteScalar, you will want to use ExecuteReader.
Something like:
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Connection"].ConnectionString);
conn.Open();
SqlCommand comm = new SqlCommand("SELECT * FROM Accounts WHERE ID = #ID AND Open = 1", conn);
comm.Parameters.AddWithValue("#ID", Session["ID"]);
using(var dataReader = comm.ExecuteReader())
{
if(dataReader.HasRows)
{
while(dataReader.Read())
{
var myRowColumn1 = dataReader["NameOfColumnInDataBase"].ToString();
}
}
}

Categories

Resources