I am a junior on C#. I have problem with Combobox. When I using SelectedItem is no working exactly, what I want. SelectedItem always return the last item in combobox, but when I using SelectedIndex is return correct result.
Example in combobox is 3 items: Admin, Moderation, Salesman. Is always return Salesman, when I using SelectedItem, even when I select Admin.
There is my code:
class ComboboxItem
class ComboboxItem
{
public string Text { get; set; }
public object Value { get; set; }
public override string ToString()
{
return Value.ToString();
}
}
add items into combobox
private void AddItemIntoComboBoxGroup()
{
string query = "SELECT* FROM kites_mango.staff_group; ";
DBUtility data = new DBUtility();
List<string>[] list = data.Select(query);
if (list != null && list[0].Count() > 0)
{
ComboboxItem item = new ComboboxItem();
for (int i = 0; i < list[0].Count(); i++)
{
item.Value = list[0][i];
item.Text = (list[1][i] + " - " + list[0][i]);
CbBGroup.Items.Add(item);
}
}
}
get selected item
if (CbBGroup.SelectedItem != null)
{
MessageBox.Show(CbBGroup.SelectedIndex + "/" + CbBGroup.SelectedItem.ToString());
}
You're instancing the ComboboxItem object before the for loop. This way, for each loop in your for statement, you're changing the properties of the same object, making objects that were loaded before in the list are also modified. That is, your list could have 3 itens, but they are going to have the same value (Salesman) because all the itens in your list have the same object reference.
Just change from this:
ComboboxItem item = new ComboboxItem();
for (int i = 0; i < list[0].Count(); i++)
{
item.Value = list[0][i];
item.Text = (list[1][i] + " - " + list[0][i]);
CbBGroup.Items.Add(item);
}
To this:
for (int i = 0; i < list[0].Count(); i++)
{
ComboboxItem item = new ComboboxItem();
item.Value = list[0][i];
item.Text = (list[1][i] + " - " + list[0][i]);
CbBGroup.Items.Add(item);
}
I'm having trouble scanning through a ListView to locate a subitem matching a given string. Here's my code:
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
string date = datePicker.Value.ToShortDateString();
int count = Program.booker.listView.Items.Count;
for (int i = 0; i < count; i++)
{
ListViewItem lvi = Program.booker.listView.Items[i];
if (lvi.SubItems.Equals(date))
{
MessageBox.Show("Found!", "Alert");
Program.booker.listView.MultiSelect = true;
Program.booker.listView.Items[i].Selected = true;
}
else
{
MessageBox.Show("Nothing found for " + date, "Alert");
}
}
}
The ListView is located on the Booker form, and I'm accessing it from the Filter class. I'd like to search the entire ListView for any items matching my date string. Thanks!
You can use the FindItemWithText method.
ListViewItem searchItem = null;
int index = 0;
do
{
if (index < Program.booker.listView.Items.Count)
{
//true = search subitems
//last false param = no partial matches (remove if you want partial matches)
searchItem = Program.booker.listView.FindItemWithText(date, true, index, false);
if (searchItem != null)
{
index = searchItem.Index + 1;
//rest of code
}
}
else
searchItem =null;
} while (searchItem != null);
I have a list-box, I want to loop through all the selected items and get each selected items text value.
for (int i = 0; i < lstFieldNames.selectedItems.Count; i++)
{
string s = lstFieldNames.SelectedItems[i].ToString();
}
the value of s is "{ Item = ADDR }"
I don't need the { Item = }, I just want the text "ADDR".
What am I doing wrong, I tried a few things and nothing seems to work for me.
Well, this is a Winforms question because an ASP.NET ListBox has no SelectedItems property(notice the plural). This is important since a Winforms ListBox has no ListItems with Text and Value properties like in ASP.NET, instead it's just an Object.
You've also commented that the datasource of the ListBox is an anonymous type. You cannot cast it to a strong typed object later.
So my advice is to create a class with your desired properties:
class ListItem {
public String Item { get; set; }
}
Create instances of it instead of using an anonymous type:
var items = (from i in xDoc.Descendants("ITEM")
orderby i.Value
select new ListItem(){ Item = i.Element("FIELDNAME").Value })
.ToList();
Now this works:
foreach (ListItem i in lstFieldNames.SelectedItems)
{
String item = i.Item;
}
Note that my ListItem class is not the ASP.NET ListItem.
string s = lstFieldNames.SelectedItems[i].Text.ToString();
Note the Text property
This would fetch Selected values only.
EDIT:
foreach (object listItem in listBox1.SelectedItems)
{
string s = listItem.ToString();
}
Use this code :
string s = "";
foreach(var item in lstFieldNames.SelectedItems)
{
s += item.ToString() + ",";
}
textBox1.Text = s;
If need on one selected item from your listbox try this cod :
string s = "";
foreach(var item in lstFieldNames.SelectedItems)
{
s = item.ToString();
}
EDIT :
Try this one code
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string s = "";
foreach (var item in listBox1.SelectedItems)
{
s += item.ToString() + ",";
}
textBox1.Text = s;
}
i'm making a workbook creator in C#.net ( using visual studio )
the book is build from the text part and the question part.
all the answers for the question are inside the text and the user need to click on the right answer. if he's right then the word become green and if he's wrong it become red.
i'm creating the clickeable text with LINKBUTTON, i gave the link button CssStyle class and after the user clicking the word i want to change the class for this link to a different class.
this is the code i using for creating the linksbutton:
public void createQusetion(Panel lefttext, Panel question, string text, string
questionText, string answer)
{
string[] Qbuttonstext = text.Split(' ');
_numberWords = Qbuttonstext.Length;
for (int i = 0; i < _numberWords; i++)
{
LinkButton answerButton = new LinkButton();
if (Qbuttonstext[i] == answer)
{
answerButton.ID = "answer" + i;
}
else
{
answerButton.ID = "word" + i.ToString();
}
answerButton.Text = Qbuttonstext[i].ToString() + " ";
answerButton.CssClass = "textbuttonB4";
answerButton.Click += new EventHandler(checkAnswer);
lefttext.Controls.Add(answerButton);
}
}
and for the checking the question:
private void checkAnswer(object sender, System.EventArgs e)
{
for (int i = 0; i < _numberWords; i++)
{
if (((Control)sender).ID.ToString() != null)
{
if (((Control)sender).ID.ToString() == "answer" + i.ToString())
{
((Control)sender).CssClass = "textbuttonRight";
}
else
{
((Control)sender).CssClass = "textbuttonwrong";
}
}
}
}
the VS2010 giving me misatake for the : ((Control)sender).CssClass .
what is the right way?
You can do a type-independent control this way. It will run for all controls have Id and CssClass Properties.
private void checkAnswer(object sender, System.EventArgs e)
{
var cssClass = sender.GetType().GetProperty("CssClass");
var id = sender.GetType().GetProperty("ID").GetValue(sender, null);
for (int i = 0; i < _numberWords; i++)
{
if (id!=null)
{
if (id.ToString() == "answer" + i.ToString())
{
cssClass.SetValue(sender, "textbuttonRight", null);
}
else
{
cssClass.SetValue(sender, "textbuttonRight", null);
}
}
}
}
I have a CheckedListBox that has X number of items. These items are placed there at runtime. These items are supposed to represent reports that can be displayed in the DataGridView. What I need to do now is display the record count for each report in parenthesis right next to the report name. I tried, not for too long, to edit the actual name of the item but couldn't find out how to do it. So then, I brute forced it. Saved the items to an array, cleared the items, appended the record counts to each item in the array, created new items. Well, this has caused issues because now it's not retaining my checks and the reason why is because whenever I generate the reports, I clear the items and recreate them. Well, rather than doing another foreach loop to save the checked status, does anyone know of a way to change the text of existing items in a CheckedListBox?
Here is the code I currently have:
In the MainForm.Designer.cs:
this.clbReports.Items.AddRange(new object[] {
"Report 1",
"Report 2",
"Report 3",
"Report 4",
"Report 5",
"Report 6",
"Report 7",
"Report 8",
"Report 9",
"Report 10",
"Report 11"});
And it looks like:
And I want it to look like (but there won't all be 0's):
Here is the SelectedIndexChanged function:
private void clbReports_SelectedIndexChanged(object sender, EventArgs e)
{
string strCheckBox = clbReports.SelectedItem.ToString();
bool bShowAllIsChecked = clbReports.GetItemChecked(clbReports.FindString("Show All Error Reports"));
bool bSelected = clbReports.GetItemChecked(clbReports.FindString(strCheckBox));
int nIndex = -1;
if (strCheckBox.Contains("Show All Error Reports"))
{
foreach (string str in _strReports)
{
if (!str.Contains("Show All Error Reports") && !str.Contains("Show Tagged Records"))
{
nIndex = clbReports.FindString(str);
if (nIndex > -1)
{
clbReports.SetItemChecked(nIndex, bSelected);
}
}
}
}
else
{
if (strCheckBox.Contains("Show All Error Reports") || bShowAllIsChecked)
{
foreach (string str in _strReports)
{
nIndex = clbReports.FindString(str);
if (nIndex > -1)
{
clbReports.SetItemChecked(nIndex, false);
}
}
}
nIndex = clbReports.FindString(strCheckBox);
if (nIndex > -1)
{
clbReports.SetItemChecked(nIndex, bShowAllIsChecked ? true : bSelected);
}
}
string[] strCheckedItems = new string[clbReports.CheckedItems.Count];
clbReports.CheckedItems.CopyTo(strCheckedItems, 0);
List<string> checkBoxReportFilter = new List<string>();
foreach (ReportRecord obj in this._lstReportRecords)
{
foreach (string str in strCheckedItems)
{
if (str.Contains(obj.Description))
{
checkBoxReportFilter.Add(obj.PartID.ToString());
}
}
}
try
{
if (checkBoxReportFilter.Count == 0 && clbReports.CheckedItems.Count > 0)
{
throw new NullReferenceException();
}
_strReportFilter = String.Join(",", checkBoxReportFilter.ToArray());
}
catch (NullReferenceException)
{
_strReportFilter = "-1";
}
generateReport();
}
And here is the code where I am clearing the items, getting the report counts and creating the new items.
_lstReportRecords = _dataController.ReportList;
bool[] bChecked = new bool[clbReports.Items.Count];
int nCounter = 0;
foreach (string str in _strReports)
{
foreach (string str2 in clbReports.SelectedItems)
{
bChecked[nCounter] = str2.Contains(str);
}
nCounter++;
}
clbReports.Items.Clear();
nCounter = 0;
foreach (string str in _strReports)
{
int nCount = _lstReportRecords.Where<ReportRecord>(delegate(ReportRecord rr) {
return rr.Description == str;
}).Count();
string newReport = str + " (" + nCount + ")";
clbReports.Items.Add(newReport);
clbReports.SetItemChecked(nCounter, bChecked[nCounter]);
nCounter++;
}
Please tell me there is an easier way to do this. I tried doing foreach loops through the clbReports.Items but it wants me to cast it to a string (errored on me when trying to cast to a CheckBox) so I couldn't change the value. And even if I could cast it to a CheckBox, I have a feeling it will give me the error that Enumeration has failed because the list has been changed (or however they word it). Any and all help is welcome. Thanks.
Edit: Please know that the Report X are just so that the actual report names aren't displayed to keep it generic. However, in the code, I just copied and pasted so the Show All Error Reports and Show All Tagged Records are reports I need to check.
The right ( == most simple and most direct) answer and solution is:
this.clbReports.Items[nIndex] = "new text of the item"
yes, those items are of type "object". No, nobody minds that, string is an object too ;)
If I were you, I'd try to give the INotifyPropertyChanged Interface a go.
You Shouldn't mess with events unless necessary. this will mean you can't use the designer to create the items, but as far as I've understood, it's a runtime-modified list anyway...
In detail:
• Create A Class (e.g.'Foo') that Implements INotifyPropertyChanged (Basically this will tell any listener that the text property has changed). This class will hold the names of all entries.
• create an ObservableCollection and bind your CheckedListBox to that Collection. In WinForms you will have to create a DataBindingSource and plug your Collection to one end and the ComboBox to the other end.
• Any change made to the collection will be visible in the control.
HTH
Sebi
In order to change the items in a ListBox (or a CheckedListBox), you should change these items' ToString() result.
The easiest solution would be to create a "Holder" class, which has a reference to the report it represents. Then the Holder class' ToString() method should be something like this:
public override string ToString()
{
return String.Format("{0} ({1})", BaseStr, MyReport.RecordCount);
}
If you change MyReport.RecordCount somehow (because a report's record count changes), you can just call clbReports.Refresh(), and it'll automatically show the new value.
I think this way you don't even need the temporary array solution in the second code block; however, I'd like to suggest an alternative way of getting the item's checked state.
You can iterate through the clbReports.CheckedIndices, and fill your bChecked array with true values only for indices in that array.
Well, due to time constraints I tried something else. I went with a ListView where CheckBoxes = true and View = List. I also removed Show All Error Reports and Show Tagged Records to checkboxes outside of the list. This made it a lot easier to do the functions I wanted. Here is the new code.
MainForm.Designer.cs
//
// cbTaggedRecords
//
this.cbTaggedRecords.AutoSize = true;
this.cbTaggedRecords.Location = new System.Drawing.Point(151, 9);
this.cbTaggedRecords.Name = "cbTaggedRecords";
this.cbTaggedRecords.Size = new System.Drawing.Size(106, 17);
this.cbTaggedRecords.TabIndex = 3;
this.cbTaggedRecords.Text = "Tagged Records";
this.cbTaggedRecords.UseVisualStyleBackColor = true;
this.cbTaggedRecords.CheckedChanged += new System.EventHandler(this.ShowTaggedRecords_CheckChanged);
//
// cbAllErrorReports
//
this.cbAllErrorReports.AutoSize = true;
this.cbAllErrorReports.Location = new System.Drawing.Point(6, 9);
this.cbAllErrorReports.Name = "cbAllErrorReports";
this.cbAllErrorReports.Size = new System.Drawing.Size(102, 17);
this.cbAllErrorReports.TabIndex = 2;
this.cbAllErrorReports.Text = "All Error Reports";
this.cbAllErrorReports.UseVisualStyleBackColor = true;
this.cbAllErrorReports.CheckedChanged += new System.EventHandler(this.ShowAllErrorReports_CheckChanged);
//
// listView1
//
this.listView1.CheckBoxes = true;
listViewItem1.StateImageIndex = 0;
listViewItem2.StateImageIndex = 0;
listViewItem3.StateImageIndex = 0;
listViewItem4.StateImageIndex = 0;
listViewItem5.StateImageIndex = 0;
listViewItem6.StateImageIndex = 0;
listViewItem7.StateImageIndex = 0;
listViewItem8.StateImageIndex = 0;
listViewItem9.StateImageIndex = 0;
this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
listViewItem1,
listViewItem2,
listViewItem3,
listViewItem4,
listViewItem5,
listViewItem6,
listViewItem7,
listViewItem8,
listViewItem9});
this.listView1.Location = new System.Drawing.Point(6, 29);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(281, 295);
this.listView1.TabIndex = 1;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.View = System.Windows.Forms.View.List;
this.listView1.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.listView_ItemChecked);
MainForm.cs
private void listView_ItemChecked(object sender, ItemCheckedEventArgs e)
{
if (e != null)
{
int nLength = e.Item.Text.IndexOf("(") - 1;
string strReport = nLength <= 0 ? e.Item.Text : e.Item.Text.Substring(0, nLength);
if (e.Item.Checked)
{
_lstReportFilter.Add(strReport);
}
else
{
_lstReportFilter.Remove(strReport);
}
}
List<string> checkBoxReportFilter = new List<string>();
foreach (ReportRecord obj in this._lstReportRecords)
{
foreach (string str in _lstReportFilter)
{
if (str.ToLower().Contains(obj.Description.ToLower()))
{
checkBoxReportFilter.Add(obj.PartID.ToString());
}
}
}
try
{
if (checkBoxReportFilter.Count == 0 && listView1.CheckedItems.Count > 0)
{
throw new NullReferenceException();
}
_strReportFilter = String.Join(",", checkBoxReportFilter.ToArray());
}
catch (NullReferenceException)
{
_strReportFilter = "-1";
}
if (!bShowAll)
{
generateReport();
}
}
private void ShowAllErrorReports_CheckChanged(object sender, EventArgs e)
{
bShowAll = true;
foreach (ListViewItem lvi in listView1.Items)
{
lvi.Checked = ((CheckBox)sender).Checked;
}
_lstReportFilter.Clear();
bShowAll = false;
generateReport();
}
private void ShowTaggedRecords_CheckChanged(object sender, EventArgs e)
{
bool bChecked = ((CheckBox)sender).Checked;
if (bChecked)
{
if (!_lstReportFilter.Contains("Show Tagged Records"))
{
_lstReportFilter.Add("Show Tagged Records");
}
}
else
{
_lstReportFilter.Remove("Show Tagged Records");
}
listView_ItemChecked(null, null);
}
Code to add counts to CheckBoxes
_lstReportRecords = _dataController.ReportList;
int nTotalCount = 0;
foreach (ListViewItem lvi in listView1.Items)
{
int nCount = _lstReportRecords.Where(rr => lvi.Text.Contains(rr.Description)).Count();
nTotalCount += nCount;
lvi.Text = (lvi.Text.Contains("(") ? lvi.Text.Substring(0, lvi.Text.IndexOf("(") + 1) : lvi.Text + " (") + nCount.ToString() + ")";
}
cbAllErrorReports.Text = (cbAllErrorReports.Text.Contains("(") ? cbAllErrorReports.Text.Substring(0, cbAllErrorReports.Text.IndexOf("(") + 1) : cbAllErrorReports.Text + " (") + nTotalCount.ToString() + ")";
int nTaggedCount = _lstReportRecords.Where(rr => rr.Description.Contains("Tagged")).Count();
cbTaggedRecords.Text = (cbTaggedRecords.Text.Contains("(") ? cbTaggedRecords.Text.Substring(0, cbTaggedRecords.Text.IndexOf("(") + 1) : cbTaggedRecords.Text + " (") + nTaggedCount.ToString() + ")";
Thank you all for your help and ideas.