c# Controls in list and accessing ListBox Properties - c#

I have solved a problem I was having with grouping objects in a way, that at beginning of the program, I loop trough all controls and store all TextBox and ListBoxes in a List<Controls>.
When i try to access them i do:
foreach(var g in controlsList)
{
g.Text = "VALUE";
}
and that works, but when I try to do g.SelectedIndex = 0 its wrong, I am guessing that has to do with that property being specific to listBox. How do I solve, or get around that ?

You can simply use OfType to filter Controls:
foreach(ListBox l in Controls.OfType<ListBox>())
l.SelectedIndex = 0;

I think this is what you are looking for:
foreach (var c in Controls)
{
var listBox = c as ListBox;
if (listBox != null)
{
listBox.SelectedIndex = 0;
}
}
Each control is safely cast to a ListBox. If it is not, the result will be null and will be skipped by the if block.

To access that property you have to cast to destination type first:
foreach(var control in controlsList)
{
if(control is ListBox) // check if this control is a listbox
((ListBox)control).SelectedIndex = 0; // now it is save to cast to listbox
}
the same could be done using as operator:
foreach(var control in controlsList)
{
var listBox = control as ListBox;
if(listBox != null) // check if cast was ok
listBox.SelectedIndex = 0; // use listBox
}

You're right that the property is specific to the list box.
You need to cast this to the correct object to be able to access it.
Here's an example:
foreach(var c in controlsList)
{
c.Text = "VALUE";
if (c is ListBox)
{
ListBox listBox = c as ListBox;
listBox.SelectedIndex = 0;
}
}

Related

How to retrieve if an item in a CheckedListBox is checked or not? Winforms C#

I have a foreach() statement running through all items inside a CheckedListBox.
How can I know if a item is or not checked?
If useful here's the code:
foreach (object user in checkedListBoxUsersWhoSee.Items)
{
// Privileged = if the user is checked he has privileges;
alias = user.ToString().Substring(user.ToString().Length - 3);
SelectUserID = new SqlCommand(Properties.Resources.SelectUserID + alias, TeamPWSecureBD);
userIDAuth = (int)SelectUserID.ExecuteScalar();
InsertAuths.Parameters.AddWithValue("#idPass", idPass);
InsertAuths.Parameters.AddWithValue("#idUser", userIDAuth);
InsertAuths.Parameters.AddWithValue("#Privileged", idPass);
//Code not finished
}
for (int i = 0; i < checkedListBoxUsersWhoSee.Items.Count; i++)
{
CheckState checkState = checkedListBoxUsersWhoSee.GetItemCheckState(i);
//CheckState.Checked
//CheckState.Indeterminate
//CheckState.Unchecked
}
You can use this code :
foreach (object user in checkedListBox.Items)
{
bool Privileged = checkedListBox.GetItemCheckState(checkedListBox.Items.IndexOf(user)) == CheckState.Checked;
}
try
foreach (CheckBox user in checkedListBox1.CheckedItems)
{
}
CheckedListBox has a property CheckedItems which is a collection of the checked or indeterminate items.
var items = checkedListBoxUsersWhoSee.CheckedItems;
UPDATE
I tested adding items to a CheckedListBox and they did not appear under the CheckedItems property suggesting that by default they are initialized with the value Unchecked.
#Arvin had given the right answer but idkw he edited to a more confuse way of solving the problem.
The code below is working like a charm so please to the person who edited the correct answer stop messing around.
foreach (object user in checkedListBoxUsersWhoSee.Items)
{
Privileged = checkedListBoxUsersWhoSee.CheckedItems.Contains(user);
...
}
I used the following:
ArrayList selected = new ArrayList();
for (int i = 0; i < chkRoles.Items.Count; i++) //chkRoles being the CheckBoxList
{
if (chkRoles.GetItemChecked(i))
selected.Add(chkRoles.Items[i].ToString()); //And I just added what was checked to the Arraylist. String values
}
Easiest way:
foreach(ListItem item in checkedListBoxUsersWhoSee.Items){
if (item.Selected){
// LOGIC HERE
}
}

Store a value for an aspx checkbox?

I have a checkbox list filled by a list of ListItem, each ListItem having both text and a value like "8" or "5".
But I realized that a CheckBox does not have a value, its value is checked or not.
var listType = SettingsManager.Get("CRMCaseTypes");
var listStatus = SettingsManager.Get("CRMStatusReasons");
var listTypeItems = ParseSettingList(listType);
var listStatusItems = ParseSettingList(listStatus);
cblCRMType.DataSource = listTypeItems;
cblCRMType.DataBind();
cblCRMStatus.DataSource = listStatusItems;
cblCRMStatus.DataBind();
foreach (Control c in cblCRMStatus.Controls)
{
CheckBox cb = c as CheckBox;
if(cb != null && cb.(value........)
}
Is there some way I could store a value in each checkbox and use it again in code behind after the user clicks submit?
Thanks
Yes, you can. You can add a custom attribute to the CheckBox. You can use the HTML5 data attributes so your HTML will be HTML5 valid:
Set
foreach (Control c in cblCRMStatus.Controls)
{
CheckBox cb = c as CheckBox;
if(cb != null)
{
cb.Attributes.Add("data-MyField", myFieldVal);
}
}
Retrieve
foreach (Control c in cblCRMStatus.Controls)
{
CheckBox cb = c as CheckBox;
if(cb != null && cb.Attributes["data-MyField"].ToString())
{
// do something
}
}
How long do you want to re use it? If you want to store it temporarily, you can use session. If you want to store it longer, save it to a database or a file.
You could pull the value from the list that the checkboxes were bound to, referencing the relevant list item based on the index of the checkbox.
You could add it as an attribute -
SET:
myCheckBox.Attributes.Add("myKey","myValue");
GET:
var myKey = myCheckBox.Attributes["myKey"] != null ? myCheckBox.Attributes["myKey"].ToString() : "";
Is there some way I could store a value in each checkbox and use it again in code behind after the user clicks submit?
You can set it to a Session
Session["CbxList"] = YourCheckBoxList;
Then when you want to reference it just add the following:
if (Session["CbxList"] != null)
{
YourCheckBoxList = Session["CbxList"] as CheckBoxList;
}
and use.
I've included a link to sessions in case you or anyone else is not familiar with them:
http://msdn.microsoft.com/en-us/library/ms178581(v=vs.100).aspx
You need to look at the Items collection, not the Controls collection:
foreach (ListItem item in cblCRMStatus.Items)
{
string value = item.Value;
}
Although probably no longer needed by OP I'll add my answer since this thread still ranks highly in Google. If this is an ASPxCheckBox you can make use of the JSProperties dictionary to store your value(s) like so:
cb.JSProperties["cpMyValue"] = "MyValue";
I would then usually use a callback from a ASPxGridView or CallbackPanel to get this back to server side (which is slightly out of scope of the original question).

How to get a value from a hashtable entry

I have put all of my form controls in a hashtable thus :-
foreach (Control c in this.Controls)
{
myhash.Add(c.Name, c);
}
amongst which are two radio buttons. I would like to get the value of the buttons, ie checked or unchecked, and assign them to a variable. How can I do that please. Thanks for all and any help.
foreach (Control c in hashtable.Values)
{
if(c is RadioButton)
{
string name = x.Name;
bool isChecked = (c as RadioButton).Checked;
}
}
or if you know the name
(hashtable["name"] as RadioButton).Checked;
You can retrieve a value by a key associated with it, basically control Name is a key in hashtable you've created. So if you know a name of controls you need to access:
var control = hash[radioButtonControlName] as RadioButton;
Otherwise using LINQ OfType() and List.ForEach():
// OfType() does check whether each item in hash.Values is of RadioButton type
// and return only matchings
hash.Values.OfType<RadioButton>()
.ToList()
.ForEach(rb => { bool isChecked = rb.Checked } );
OR using foreach loop:
(there is a nice overview of misconception of the List.ForEach() usage)
var radioButtons = hash.Values.OfType<RadioButton>();
foreach(var button in radioButons)
{
bool isChecked = rb.Checked;
}
Cast the control that is the radio button to a RadioButton Class instance and then look at the checked property. At least that would be how I've done this many times over in WebForms using similar classes.
Assuming the hashtable in your code is an instance of Hashtable:
Hashtable myhash= new Hashtable();
foreach (Control c in this.Controls)
{
myhash.Add(c.Name, c);
}
You can do this:
foreach (DictionaryEntry entry in myhash)
{
RadioButton rb = entry.Value as RadioButton;
if (rb != null)
bool checked = rb.Checked;
}
Also you can see the key of the hashmap entry with:
foreach (DictionaryEntry entry in myhash)
{
var componentName = entry.Key;
}
That will correspond with the name of the component that you put in the hashmap (c.Name).
Hope this help you.

Prevent double entries in ListView using C#?

How can we access the items added to a ListView?
The thing I have to do is: add an item to the list view. I want to check if the item to add to the listview is already present in the ListView.
I'm using C# and Visual Studio 2005.
The ListView class provides a few different methods to determine if an item exists:
Using Contains on the Items collection
Using one of the FindItemWithText methods
They can be used in the following manner:
// assuming you had a pre-existing item
ListViewItem item = ListView1.FindItemWithText("test");
if (!ListView1.Items.Contains(item))
{
// doesn't exist, add it
}
// or you could find it by the item's text value
ListViewItem item = ListView1.FindItemWithText("test");
if (item != null)
{
// it exists
}
else
{
// doesn't exist
}
// you can also use the overloaded method to match sub items
ListViewItem item = ListView1.FindItemWithText("world", true, 0);
Just add your items and make sure you assign a name. Then
just use the ContainsKey method of the Items collection to
determine if it's there, like this.
for (int i = 0; i < 20; i++)
{
ListViewItem item = new ListViewItem("Item" + i.ToString("00"));
item.Name = "Item"+ i.ToString("00");
listView1.Items.Add(item);
}
MessageBox.Show(listView1.Items.ContainsKey("Item00").ToString()); // True
MessageBox.Show(listView1.Items.ContainsKey("Item20").ToString()); // False
You could do something like this:
ListViewItem itemToAdd;
bool exists = false;
foreach (ListViewItem item in yourListView.Items)
{
if(item == itemToAdd)
exists=true;
}
if(!exists)
yourListView.Items.Add(itemToAdd);
The following will help to locate a ListViewItem within the ListView control once you've added it:
string key = <some generated value that defines the key per item>;
if (!theListViewControl.Items.ContainsKey(key))
{
item = theListViewControl.Items.Add(key, "initial text", -1);
}
// now we get the list item based on the key, since we already
// added it if it does not exist
item = theListViewControl.Items[key];
...
Note
The key used to add the item to the ListView items collection can be any unique value that can identify the ListViewItem within the collection of items. For example, it could be a hashcode value or some property on an object attached to the ListViewItem.
A small correction in Robban's answer
ListViewItem itemToAdd;
bool exists = false;
foreach (ListViewItem item in yourListView.Items)
{
if(item == itemToAdd)
{
exists=true;
break; // Break the loop if the item found.
}
}
if(!exists)
{
yourListView.Items.Add(itemToAdd);
}
else
{
MessageBox.Show("This item already exists");
}
In case of multicolumn ListView, you can use following code to prevent duplicate entry according to any column:
Let us suppose there is a class Judge like this
public class Judge
{
public string judgename;
public bool judgement;
public string sequence;
public bool author;
public int id;
}
And i want to add unique object of this class in a ListView. In this class id is unique field, so I can check unique record in ListView with the help of this field.
Judge judge = new Judge
{
judgename = comboName.Text,
judgement = checkjudgement.Checked,
sequence = txtsequence.Text,
author = checkauthor.Checked,
id = Convert.ToInt32(comboName.SelectedValue)
};
ListViewItem lvi = new ListViewItem(judge.judgename);
lvi.SubItems.Add(judge.judgement ? "Yes" : "No");
lvi.SubItems.Add(string.IsNullOrEmpty(judge.sequence) ? "" : txtsequence.Text);
lvi.SubItems.Add(judge.author ? "Yes" : "No");
lvi.SubItems.Add((judge.id).ToString());
if (listView1.Items.Count != 0)
{
ListViewItem item = listView1.FindItemWithText(comboName.SelectedValue.ToString(), true, 0);
if (item != null)
{
// it exists
}
else
{
// doesn't exist
}
}

How do you access a Control in a collection by its Type?

How does one target a control by its Type?
I have a Control collection "TargetControls"
List<Control> TargetControls = new List<Control>();
foreach (Control page in Tabs.TabPages)
{
foreach (Control SubControl in page.Controls)
TargetControls.Add(SubControl);
}
foreach (Control ctrl in TargetControls)...
I need to access each existing control (combobox,checkbox,etc.) by its specific Type with access to its specific properties. The way I'm doing it now only gives me access to generic control properties.
Can't I specify something like...
Combobox current = new ComboBox["Name"]; /// Referencing an Instance of ComboBox 'Name'
and then be given access to it's (already existing) properties for manipulation?
You can use the is keyword to check for a specific type of the control. If the control is of a specific type, do a typecast.
foreach (Control SubControl in page.Controls)
{
if (SubControl is TextBox)
{
TextBox ctl = SubControl as TextBox;
}
}
You can use the OfType<T> extension method:
foreach (var textBox = page.Controls.OfType<TextBox>()) {
// ...
}
You'll need to cast the control to the right type of control before accessing any specific parameters.
ComboBox c = ctrl as ComboBox;
If (c != null)
{
//do some combo box specific stuff here
}
Also you could add the controls to a generic dictionary<string, control> and use the control.name as the key there.
Ex.
Dictionary<string, Control> TargetControls = new Dictionary<string, Control>();
Assuming you can use LINQ, and you're looking for (say) a Button control:
var button = (from Control c in TargetControls
where c.Name == "myName" && c is Button
select c
).FirstOrDefault();
...which will give you the first Button control named "myName" in your collection, or null if there are no such items present.
What about the Find method?
Button btn = (Button)this.Controls.Find("button1", true)[0];
btn.Text = "New Text";
In order to access a control's specific properties, you have to cast it to its appropriate type. For example, if the item in your TargetControls collection was a textbox, you would have to say ((TextBox)TargetControls[0]).Text = 'blah';
If you don't know the types ahead of time, you can use reflection to access the properties, but I'd need to have a better example of what you're trying to do first...

Categories