EB's Electronics
EB's Electronics

Reputation: 39

Loading information from a SQL DB to an array of buttons, they are not in order

I am writing a point-of-sale (POS) app where I have the layout number (1-35), text (price and product name) and image of the buttons in a SQL database. There is a ItemLayout table in the database, that includes the item ID (PLU), the layout number (1-35), if the button should be visible in the first place (all working) and the group of the item. They are read with the following function:

public ILMButtonsProps[] getILMButtonProps(string GroupName)
{
    ILMButtonsProps[] result = new ILMButtonsProps[getILMAmount(GroupName)];
    try
    {
        SqlConnection con = new SqlConnection(returnConString());
        con.Open();

        string operation = "SELECT * FROM ItemLayout WHERE ItemGroup=@ItemGroup";
        SqlCommand cmd = new SqlCommand(operation, con);
        cmd.Parameters.AddWithValue("@ItemGroup", GroupName);
        SqlDataReader reader = cmd.ExecuteReader();

        int count = 0;
        while (reader.Read())
        {
            result[count] = new ILMButtonsProps();
            result[count].ItemGroup = reader["ItemGroup"].ToString();
            result[count].LayoutNumber = reader["Number"].ToString();
            result[count].Enable = Convert.ToInt32(reader["Enable"].ToString());
            result[count].PLU = reader["PLU"].ToString();

            count++;
        }
        reader.Close();
        con.Close();

    }
    catch (Exception ex)
    {
        helperClass.throwError(ex.Message, ex.Source);
    }
    return result;
}

The function used to get the length for the array:

public int getILMAmount(string GroupName)
{
    int result = 0;
    try
    {
        SqlConnection con = new SqlConnection(returnConString());
        con.Open();

        string operation = "SELECT * FROM ItemLayout WHERE ItemGroup=@GroupName";
        SqlCommand cmd = new SqlCommand(operation, con);
        cmd.Parameters.AddWithValue("@GroupName", GroupName);
        SqlDataReader reader = cmd.ExecuteReader();

        while (reader.Read())
        {
            result++;
        }
        reader.Close();
        con.Close();

    }
    catch (Exception ex)
    {
        helperClass.throwError(ex.Message, ex.Source);
    }
    return result;
}

And the class used (I don't think this is very important here but anyways:)

internal class  ILMButtonsProps
{
    internal string ItemGroup;
    internal string LayoutNumber;
    internal int Enable;
    internal string PLU;
}

Here is also the table in the table designer:

When I call the getILMButtonProps function using the next bit of code, I get all of the results in a weird pattern.

//Load buttons
ILMButtonsProps[] array = SQL.getILMButtonProps(cmbILMGroups.SelectedItem.ToString());
int counter = 0;
int max = array.Length;
Button[] btns = panel4.Controls.OfType<Button>().ToArray();

if (array == null)
{
    helperClass.throwError("There was an error reading the arrangements for the buttons in the database! Please try again...", "NPManager");
    return;
}

for (int x = 0; x < max; x++)
{
    //If all props are set, exit loop
    if (counter == max || counter == 35) { break; }

    //If there is a null in the layout, skip it.
    if (array[counter] == null)
    {
        counter++;
        return;
    }

    //Enable t/f
    //Get details from DB and input to buttons
    int i = Convert.ToInt32(array[counter].LayoutNumber);
    if (array[counter].Enable == 1)
    {
        btns[i].Text = "";
        btns[i].BackgroundImage = NPManager.Properties.Resources._109_AllAnnotations_Error_24x24_72;
    }

    if (array[counter].Enable == 2)
    {
        ILMDataPoints dp = SQL.getDataRowFromPLU(array[counter].PLU);

        btns[i].Text = dp.itemName + " @ " + dp.itemPrice;
        if(dp.image == null)
        {
            btns[i].BackgroundImage = null;
            btns[i].ForeColor = Color.Black;
        }
        if (dp.image != null && string.IsNullOrEmpty(dp.image.ToString()) && dp.image == System.DBNull.Value && dp.image.ToString() == "{}")
        {
            btns[i].BackgroundImage = GetImageFromByteArray((byte[])dp.image);

            PictureAnalysis pictureAnalysis = new PictureAnalysis();
            btns[i].ForeColor = GetReadableForeColor(pictureAnalysis.GetMostUsedColor(GetImageFromByteArray((byte[])dp.image))); //N
        }
    }

    counter++;
}

The ILMDatapoints (dp) variable is a custom class

Here is the result: Output

As you can see, the buttons arrangement is alternating from the top and bottom, but I want it to be from left to right. I don't understand how this is possible, as I am using multiple ways to ensure that the buttons and properties are in their correct order (numerical order). When I debug the the button array above, it shows that they're in the correct order, although I think this may be wrong, as I see it as the only point where the buttons could get messed up.

Upvotes: 0

Views: 67

Answers (2)

EB&#39;s Electronics
EB&#39;s Electronics

Reputation: 39

For anyone in the future who needs the solution, it is to sort the buttons in the btns[]

Here is what I did: Button[] btns = panel4.Controls.Cast<Button>().OrderBy(x => Convert.ToInt32(x.Tag)).ToArray();

Here is the result:

I used the tag on the buttons to make this possible.

Thank you to Fildor (see comment on problem above) and Lân Vũ for the solution.

Upvotes: 1

Diogo Ribeiro
Diogo Ribeiro

Reputation: 1

Try ordering by the layoutnumber in the SQL query

Upvotes: 0

Related Questions