I have a combobox in my WinForms application in which you can search for a string and results are filtered accordingly, but it seems to behave very strangely. I am searching for "Coo" and I get a very long list of products that do not contain the string "coo" (http://prntscr.com/pr54rs). However, when I type in "coor" and then press backspace, leaving me with "coo" again, the list of results is different (http://prntscr.com/pr55ef)
I am using the "KeyPress" event handler to search in the combobox. The code looks like this
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
{
comboBox1.Items.Clear();
listNew.Clear();
var source = new AutoCompleteStringCollection();
foreach (var item in listOnit)
{
if (item.ToLower().Contains(this.comboBox1.Text.ToLower()))
{
listNew.Add(item);
}
}
comboBox1.Items.AddRange(listNew.ToArray());
comboBox1.SelectionStart = this.comboBox1.Text.Length;
Cursor = Cursors.Default;
comboBox1.DroppedDown = true;
}
Am I doing something wrong? The list is populated from a database
string sqlProducts = "SELECT Description FROM stocktake_products WHERE stocktake_id = '" + stocktakeID.stocktake_id + "' AND (PLUProdCode IS NULL OR PLUProdCode = '');";
MySqlCommand cmdProduct = new MySqlCommand(sqlProducts, conn);
cmdProduct.CommandTimeout = 10000;
MySqlDataReader rdrProduct = cmdProduct.ExecuteReader();
AutoCompleteStringCollection myCollectionSales1 = new AutoCompleteStringCollection();
if (rdrProduct.HasRows == true)
{
while (rdrProduct.Read())
{
// myCollectionSales1.Add(rdrProduct[0].ToString());
listOnit.Add(rdrProduct[0].ToString());
}
rdrProduct.Close();
//textBox1.AutoCompleteCustomSource = myCollectionSales1;
comboBox1.Items.AddRange(listOnit.ToArray());
}
I want the combobox to only display results that contain the whole string that has been typed in, not every phrase that has typed letters in any position as it seems like that's what it is doing.
I have tried to include the BeginIvoke method (not sure if done correctly thought as I have never used it before)
this.BeginInvoke((MethodInvoker)delegate
{
comboBox1.Items.Clear();
listNew.Clear();
var source = new AutoCompleteStringCollection();
foreach (var item in listOnit)
{
if (item.ToLower().Contains(this.comboBox1.Text.ToLower()))
{
listNew.Add(item);
}
}
comboBox1.Items.AddRange(listNew.ToArray());
comboBox1.SelectionStart = this.comboBox1.Text.Length;
Cursor = Cursors.Default;
comboBox1.DroppedDown = true;
});
Now when I start typing the first character, the combobox selects to top result right away (http://prntscr.com/pr5f6i). I have to press the first character again and then type the rest of the string to be able to actually search through the list.
Related
I have a listbox with a list of items that get loaded when you navigate to a certain page. Then I have an on click that passes parameters to an AddProducts method. That method is what loops through all selected items and inserts values from the fields filled in as well as takes the values from the listItems and adds them as parameters to a stored procedure.
The problem I'm running into is that when looping through the listItems
if(selectedItem.Selected) is returning false, but in my method where I load the listbox I initialize a SelectedValue so I'm not sure why it's giving me the error message I have for no selected items. I was able to get it to work yesterday before I moved LoadListBoxCategories outside of LoadAddData but unsure as to why that would have any effect to if(listItem.Selected).
I'm relatively new to asp.net so any help/ explanation as to why my code isn't working is extremely appreciated. I've spent the last three days trying to figure this out and haven't found a solution that works.
Code:
Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
if (Session[IS_LOGGED_IN] == null)
{
Response.Redirect("/utilities/companydata/login.aspx", true);
return;
}
gvTextInputs.RowEditing += new GridViewEditEventHandler(gvTextInputs_RowEditing);
if (!IsPostBack)
{
string pageId = Request.QueryString["pageid"];
string productId = Request.QueryString["productid"];
/* Add Mode */
if (!string.IsNullOrEmpty(pageId))
{
SetMode(MODE_ADD, "");
LoadAddData(pageId);
LoadListBoxCategories(pageId);
}
else if (!string.IsNullOrEmpty(productId))
{
string imageServer;
if (LoadProductData(productId, out imageServer))
{
InitImageGridview();
InitTextGridview();
InitStaticGridview();
SetMode(MODE_EDIT, imageServer);
SetImageServer(imageServer);
}
else
{
//TO DO - Return Error
}
}
}
else
{
InitImageGridview();
InitTextGridview();
InitStaticGridview();
}
}
Load ListBox:
private void LoadListBoxCategories(string pageId)
{
listBoxCategories.Visible = true;
//This gets query is so I can store the CompanyId and the CombinedValue data from pageId
string select = "SELECT companyName, cl.GbsCompanyId, cl.companyId, wpt.productTypeId, productName, (CAST(wp.pageId as varchar(200)) +'|'+ CAST(wp.productTypeId as varchar(200)) + '|' ) AS CombinedValue FROM CompanyList cl, WtpPages wp, WtpProductTypes wpt WHERE cl.companyId=wp.companyId AND wpt.productTypeId=wp.productTypeId AND wp.pageId=#pageId";
SqlDataSource connectionId = new SqlDataSource(DB_CONNECT, select);
connectionId.SelectParameters.Add("pageId", pageId);
DataView dView = (DataView)connectionId.Select(DataSourceSelectArguments.Empty);
if (dView.Table.Rows.Count == 1)
{
string companyId = dView.Table.Rows[0]["companyId"].ToString();
string curCategoryProductTypeId = dView.Table.Rows[0]["CombinedValue"].ToString();
// EXEC MCAdmin_GetAllCategoriesByCompanyId #companyId
// Lists All Categories #companyId has Active
string selectLoadData = "EXEC MCAdmin_GetAllCategoriesByCompanyId #companyId";
SqlDataSource conn = new SqlDataSource(DB_CONNECT, selectLoadData);
conn.SelectParameters.Add("companyId", companyId);
lstCategoriesBox.Items.Clear();
lstCategoriesBox.Items.Add(new ListItem("--Select--", null));
lstCategoriesBox.DataTextField = "productName";
lstCategoriesBox.DataValueField = "CombinedValue";
// Pre-selects the value of the productTypeId you are trying to add a product for
// to send later run against a foreach insert in AddProduct()
lstCategoriesBox.SelectedValue = curCategoryProductTypeId;
testOutcomeCategory.InnerText = curCategoryProductTypeId;
lstCategoriesBox.DataSource = conn;
lstCategoriesBox.DataBind();
}
}
AddProduct:
private string AddProduct(string companyId, out string errMsg)
{
foreach (ListItem selectedItem in lstCategoriesBox.Items)
{
if (selectedItem.Selected)
{
// assign current productTypeId & pageId from selected Categories new CombinedValue column
string[] splitColumnValue = selectedItem.Value.Split('|');
string selectedPageId = splitColumnValue[0].ToString();
string selectedProductTypeId = splitColumnValue[1].ToString();
SqlDataSource connnection = new SqlDataSource(DB_CONNECT, "");
connnection.InsertCommand = "EXEC MCAdmin_AddProductFromClassic #pageId, #productTypeId, #productCode, #imgDirectory, #numSides, #sortOrder, #isActive, #template, #template2, #template3, #EditorJson, #MockupTemplateBase, #MockupTemplateTreatment, #BorderDefault ";
connnection.InsertParameters.Add("pageId", selectedPageId);
connnection.InsertParameters.Add("productTypeId", selectedProductTypeId);
connnection.InsertParameters.Add("productCode", txtProductCode.Text);
connnection.InsertParameters.Add("numSides", ddlNumSides.SelectedValue);
connnection.InsertParameters.Add("sortOrder", txtSortOrder.Text);
connnection.InsertParameters.Add("isActive", ddlActive.SelectedValue);
connnection.InsertParameters.Add("template", txtTemplate1.Text);
connnection.InsertParameters.Add("template2", txtTemplate2.Text);
connnection.InsertParameters.Add("template3", txtTemplate3.Text);
connnection.InsertParameters.Add("EditorJson", txtJson.Text);
connnection.InsertParameters.Add("MockupTemplateBase", txtMockupTemplateBase.Text);
connnection.InsertParameters.Add("MockupTemplateTreatment", txtMockupTemplateTreatment.Text);
connnection.InsertParameters.Add("BorderDefault", txtBorderDefault.Text);
/* Special Product Code for Upload Artwork Business Card */
if (txtProductCode.Text.ToUpper() == "BPFAH1-001-100")
{
connnection.InsertParameters.Add("imgDirectory", "/images/business-cards/general/");
}
else
{
connnection.InsertParameters.Add("imgDirectory", ddlImgDir.SelectedValue);
}
int result = connnection.Insert();
if (result > 0)
{
SqlDataSource connect = new SqlDataSource(DB_CONNECT, "");
connect.SelectCommand = "SELECT TOP 1 wtpProductId FROM WtpProducts ";
connect.SelectCommand = "WHERE productTypeId=#productTypeId AND pageId=#pageId DESC ";
connect.SelectParameters.Add("pageId", selectedPageId); //
connect.SelectParameters.Add("productTypeId", selectedProductTypeId); //
DataView dView = (DataView)connect.Select(DataSourceSelectArguments.Empty);
if (dView.Table.Rows.Count == 1)
{
string wtpProductId = dView.Table.Rows[0]["wtpProductId"].ToString();
errMsg = "";
return wtpProductId;
}
else
{
errMsg = "ERROR: Could not get productId of newly created Product.";
return "0";
}
}
else
{
errMsg = "ERROR: Could not add WtpProduct record to DB";
return "0";
}
}
else
{
errMsg = "ERROR: You must select a Category";
return "0";
}
}
errMsg = "ERROR: Did not make it into the foreach loop";
return "0";
}
OnClick method:
protected void OnClick_btnAddProduct(object sender, EventArgs e)
{
string pageId = Request.QueryString["pageid"];
testOutcomeCategory.InnerText = lstCategoriesBox.SelectedValue; // This proves that I have something selected!!!
string select = "SELECT companyName, cl.GbsCompanyId, cl.companyId, wpt.productTypeId, productName, baseImgDirectory, templateDirectory, wp.imageServer FROM CompanyList cl, WtpPages wp, WtpProductTypes wpt WHERE cl.companyId=wp.companyId AND wpt.productTypeId=wp.productTypeId AND wp.pageId=#pageId";
SqlDataSource conn = new SqlDataSource(DB_CONNECT, select);
conn.SelectParameters.Add("pageId", pageId);
DataView dView = (DataView)conn.Select(DataSourceSelectArguments.Empty);
if(dView.Table.Rows.Count == 1)
{
string companyId = dView.Table.Rows[0]["companyId"].ToString();
if (!string.IsNullOrEmpty(pageId))
{
string errMsg;
string productId = AddProduct(companyId, out errMsg);
if(productId != "0")
{
Response.Redirect("/utilities/companydata/add-edit-wtp-product.aspx?productid=" + productId, true);
SetStatusMsg("Success", false);
}
else
{
SetStatusMsg(errMsg, true);
}
}
}
}
The list box instance is recreated on the server-side during the postback (as well as entire page). You do not set the selected items in the Page_Load event handler - if (!IsPostBack) goes to else branch. This is why you don't see them.
Ok,
lstCategoriesBox.Items.Clear();
Ok, above goes nuclear - blows out the list, blows out the selection.
Ok, that's fine
lstCategoriesBox.Items.Add(new ListItem("--Select--", null));
lstCategoriesBox.DataTextField = "productName";
lstCategoriesBox.DataValueField = "CombinedValue";
Ok, above adds a new item. Should be ok, but one should setup the lb BEFORE adding any data - including that "--select--" row.
It just makes sense to "setup" the lb and THEN start adding data, right?
However, But, if above works - ok, then lets keep going, but I would setup the lb before adding any rows of data. Say like this:
lstCategoriesBox.DataTextField = "productName";
lstCategoriesBox.DataValueField = "CombinedValue";
lstCategoriesBox.Items.Add(new ListItem("--Select--", null));
Now, the next line:
lstCategoriesBox.SelectedValue = curCategoryProductTypeId;
Ouch! - we just cleared the lb, and now we trying to set it to a value? You can't do that - the lb just been cleared, right? You would need to load up the lb first, and THEN you can set it to the selected value, right?
I might be missing something here, but that lb needs to be loaded up with valid data BEFORE you attempt to set the selected value?
To test first, change following
Outcome Category.InnerText = list CategoriesBox.SelectedValue;
to
Category.InnerText = Request.Form["CategoriesBox-ClientID"]
If the data is coming in correctly, the list view cleared or reloaded when between reload and click events the page.
UPDATE: I just figured it out! So stupid but when I check if(selectedItem.Selected) since I'm looping through the ListBox items it starts at the first index of the ListBox and since the first isn't selected then that if goes to the else block. Remove the else and it works fine
I'm creating a to-do list in C# Win Forms. I want to use my own checkboxes since you can't change the size of the checkboxes in visual studio. I'm using two pictures to be placed in a picture box, one empty check box and one checkbox with an X in it. When the user clicks a checkbox I want to use a function to change the picture in the box; if the check box is empty then I want the click to change the picture to the X filled box, and vice versa. There's a database that saves whether the user checks the box, a 0 for empty and a 1 for checked. I know I could just code each click event to respond individually, but I wanted to use a function to cut down on the code.
This is what I have so far. The function to update the picture.
private static String UpdateCheck(string checkPosition, int picBox)
{
ToDo td = new ToDo();
PictureBox[] pb = { td.checkMark1, td.checkMark2, td.checkMark3, td.checkMark4, td.checkMark5, td.checkMark6, td.checkMark7,
td.checkMark8, td.checkMark9, td.checkMark10};
if (checkPosition == "0")
{
pb[picBox].Image= Image.FromFile("C:/Users/royet/source/repos/Last Time/checkedCheckbox.png");
checkPosition = "1";
MessageBox.Show(checkPosition);
return checkPosition;
}
else if (checkPosition == "1")
{
pb[picBox].Image = Image.FromFile("C:/Users/royet/source/repos/Last Time/checkbox111.png");
checkPosition = "0";
MessageBox.Show("Hi");
return checkPosition;
}
else
{
return checkPosition;
}
}
The click event
private void checkMark1_Click(object sender, EventArgs e)
{
ToDo td = new ToDo();
string cp = td.checkPos1;
int pb = 5;
td.checkPos1 = UpdateCheck(cp, pb);
}
The main code
string checkPos1, checkPos2, checkPos3, checkPos4, checkPos5, checkPos6,
checkPos7, checkPos8, checkPos9, checkPos10;
public ToDo()
{
InitializeComponent();
//Reads data from db and places it into textboxes
string constr = #"Data Source=MasterBlaster\SQLEXPRESS;Initial Catalog=Final;Integrated Security=True";
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("SELECT Checked1, Checked2, Checked3, Checked4," +
"Checked5, Checked6, Checked7, Checked8, Checked9, Checked10 FROM ToDoDB"))
{
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
con.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
sdr.Read();
checkPos1 = sdr["Checked1"].ToString();
checkPos2 = sdr["Checked2"].ToString();
checkPos3 = sdr["Checked3"].ToString();
checkPos4 = sdr["Checked4"].ToString();
checkPos5 = sdr["Checked5"].ToString();
checkPos6 = sdr["Checked6"].ToString();
checkPos7 = sdr["Checked7"].ToString();
checkPos8 = sdr["Checked8"].ToString();
checkPos9 = sdr["Checked9"].ToString();
checkPos10 = sdr["Checked10"].ToString();
}
con.Close();
}
}
string[] checks = { checkPos1, checkPos2, checkPos3, checkPos4, checkPos5, checkPos6, checkPos7, checkPos8, checkPos9, checkPos10 };
PictureBox[] boxes = { checkMark1, checkMark2, checkMark3, checkMark4, checkMark5, checkMark6, checkMark7, checkMark8, checkMark9, checkMark10 };
for (int i = 0; i < checks.Length; i++)
{
if (checks[i] == "0")
{
boxes[i].Image = Image.FromFile("C:/Users/royet/source/repos/Last Time/checkbox111.png");
}
else if (checks[i] == "1")
{
boxes[i].Image = Image.FromFile("C:/Users/royet/source/repos/Last Time/checkedCheckbox.png");
}
}
}
Everything works great, there are no errors. But when I load the program and try to click the first picturebox, the picture won't change. I added in the messagebox to see if the code was working at all, and it was. Everything in the function works except for the picture getting changed. The picture stays the same. What am I doing wrong?
I have the following function which works fine and produces the results when their is one table selected. But when there is two tables being selected my _newList function is just replacing the fields in the array I will show you in graphical form best i can.
private void genXmlSchema_Click(object sender, EventArgs e)
{
List<TableDefnition> _newList = new List<TableDefnition>();
PersistentObject _testObjects = new PersistentObject();
List<GridViewRowInfo> _checkRows = GetCheckedRows(rgTableNames);
List<PersistentObject> _testObjectsList = new List<PersistentObject>();
foreach (GridViewRowInfo row in _checkRows)
{
var currentRow = (TableNames)row.DataBoundItem;
_newList = db.GetALLTableDeiniations(currentRow.TABLE_NAME);
rgFieldsOfTable.DataSource = db.GetALLTableDeiniations(currentRow.TABLE_NAME);
_testObjectsList.Add( BuildSchema(_newList, currentRow.TABLE_NAME));
}
_newPObject.PersistentObjects.AddRange(_testObjectsList);
_newPObject.ClassPrefix = "Persistent";
_newPObject.ClassSuffix = "";
_newPObject.Language = "VB";
_newPObject.Path = #"C:\Sage200SchemaExtensions";
_newPObject.GenerateSeparateFiles = "false";
_newPObject.GenerateBusinessObjects = "false";
_newPObject.BaselineSchema = #"C:\Program Files (x86)\Sage 200 SDK\SageObjectStore.xml";
_newPObject.DataTypes = "";
_newPObject.Enumerations = "";
_newPObject.MemberVariablePrefix = "_";
_newPObject.ApplicationNamespace = "BusinessObjects";
schemeContent.Text = HelperXml.ToXML(_newPObject);
}
On the second pass you will that it has duplicated the second table in both of the lists.
First Array Number after second pass
Second Array Number after second pass
As you can clearly see its lost the reference to the first table with 4 columns completely I no its something simple to do with my list creation and destruction but cant figure it out
My form has a textBox and i want to add autocomplete while typing.
My autocomplete values are loaded dynamically via a json api.
I applied the "update" function on the "TextChanged" Event of the textBox.
Everytime it is triggered, the autocomplete opens for 0.5 sec and the textBox's value changes to the first autocomplete entry. After that the autocomplete menu disappears.
I cannot choose any suggestions manuelly...
How to fix?
onload Event:
AutoCompleteStringCollection colValues = new AutoCompleteStringCollection();
private void StellenUebersicht_Load(object sender, EventArgs e)
{
TextBox textBoxExample = textBox1;
textBoxExample.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
textBoxExample.AutoCompleteSource = AutoCompleteSource.CustomSource;
textBoxExample.AutoCompleteCustomSource = colValues;
doAutoCompleteListExample();
}
doAutoCompleteListExample():
private void doAutoCompleteListExample()
{
if (textBox1.Text.Length >= 1)
{
string w = Web.get("MY JSON API URL");
JObject o = JObject.Parse(w);
List<string> ac = new List<string>();
foreach (JObject item in o["items"])
{
string name = item["name"].ToString();
ac.Add(name);
}
colValues.AddRange(ac.ToArray());
}
}
i fixed it.
Solution:
change
textBoxExample.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
to
textBoxExample.AutoCompleteMode = AutoCompleteMode.Suggest;
just delete your If,no need If... do this if you not sure
// if (textBox1.Text.Length >= 1)
// {
string w = Web.get("MY JSON API URL");
JObject o = JObject.Parse(w);
List<string> ac = new List<string>();
foreach (JObject item in o["items"])
{
string name = item["name"].ToString();
ac.Add(name);
}
colValues.AddRange(ac.ToArray());
// }
maybe this help you
The properties like AutoCompleteCustomSource, AutoCompleteMode and AutoCompleteSource to perform a TextBox that automatically completes user input strings by comparing the prefix letters being entered to the prefixes of all strings in a data source.
textBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
AutoCompleteStringCollection DataCollection = new AutoCompleteStringCollection();
addItems("Add your Data here");
textBox1.AutoCompleteCustomSource = DataCollection;
Full source here.
I have a routine that populates a combobox from a database; the first time the combo is populated, it all works perfectly, but if I try to do it again, the combobox is completely blank. I narrowed it down to this line:
cboThis.DataSource = cboThis.Items;
This seems to clear the Items collection for the combobox...but only if the combo was already populated.
Any ideas what could be going on here?
There IS an event handler for one of the combo's SelectedIndexChanged event, but this doesn't seem to get called by anything but the first and last lines of code.
Here's the complete routine:
public void ComboFromDB(ComboBox cboThis, string strTable, string strField)
{
cboThis.SelectedIndex = -1;
cboThis.DataSource = null;
cboThis.Items.Clear();
string strQuery = #"SELECT ID, " + strField + " FROM " + strTable;
using (SqlConnection sqcConnection = new SqlConnection(strConnection))
{
sqcConnection.Open();
SqlCommand sqcCommand = new SqlCommand(strQuery, sqcConnection);
SqlDataReader dr = sqcCommand.ExecuteReader();
while (dr.Read())
{
cboThis.Items.Add(new ComboItem((int)dr[0], dr[1].ToString())); //this all works fine
}
}
cboThis.DataSource = cboThis.Items; //This line clears cboThis.Items...
cboThis.ValueMember = "ID";
cboThis.DisplayMember = "Display";
cboThis.SelectedIndex = -1;
}
Cheers
try to create a structure like this
struct tmpItems
{
//member variables
private Int32 _ID;
private String _Display;
//properties
public Int32 ID
{
get {return _ID;}
}
public String Display
{
get {return _Display;}
}
public tmpItems(Int32 pID , String pDisplay)
{
_ID = pID;
_Display = pDisplay;
}
}
now assign
ArrayList dataItems = new ArrayList();
dataItems.Add(new tmpItems((int)dr[0], dr[1].ToString()));
then finally set
cbothis.DataSource = dataItems;
cboThis.ValueMember = "ID";
cboThis.DisplayMember = "Display";
Ensure that ComboBox SelectedIndexChange event handles the Initialization of data..
because while setting datasource , the items will be added one by one.. each time generating SelectedIndexChangeEvent .. but will find difficult in accessing SelectedValue property at this stage
In the end I binned using Items and just shoved it through a Dictionary.