I am struggling with filtering of listView. I tried 2 methods to filter without selected items removed.
My issue: whenever an selected item disappers because of the filter, it is no longer selected when it comes back.
My methods:
Self written code:
try
{
string s = isci_tb.Text;
if (isci_tb.Text == "")
{
osebe_listView.Items.Clear();
foreach (Oseba o in seznamOseb)
{
osebe_listView.Items.Add(o);
}
}
else
{
osebe_listView.Items.Clear();
foreach (Oseba o in seznamOseb)
{
if (contejns(o.ime, s) || contejns(o.priimek, s) || contejns(o.mobilnaSt.ToString(), s) || contejns(o.posta, s) || contejns(o.nazivPodjetja, s) || contejns(o.stacionarnaSt.ToString(), s) || contejns(o.naslov, s) || contejns(o.eMail, s))
{
osebe_listView.Items.Add(o);
}
}
}
}
catch { }
What this does is it searches all items and displayes only the one that matches with he filter, but this method removes items comepletly and re-adds them.
I tried to add a value for selected items, that saves onSelectionChanged and is used when the filter is changed, but it didn't work.
The second method was from this tutorial. I was hoping it would work because it uses a Filter, but aparently, it has the same issue.
You could try setting the Visibility of your ListViewItems depending on some property of Oseba. Then, instead of
osebe_listView.Items.Clear();
foreach (Oseba o in seznamOseb)
{
if (someConditions)
{
osebe_listView.Items.Add(o);
}
}
You could write something like this:
foreach (Oseba o in seznamOseb)
{
if (someConditions) // when true, we want to hide the object
{
o.IsVisible = false;
}
}
and in your .xaml file use a DataTemplate which sets the item's Visibility to Collapsed when IsVisible is set to false.
Another approach would be to store the IsSelected-state inside your object Oseba, so that when you remove and re-add the object to your listView, the selection state is persistent.
i made this code for get all the groupboxes from a winform and then take only the ones with a determinated name.
Control.ControlCollection controles = this.Controls;
GroupBox gBoxAux = new GroupBox();
List<GroupBox> gBoxes = new List<GroupBox>();
foreach (Control c in controles)
{
if (c.GetType() == typeof(GroupBox))
{
gBoxAux = (GroupBox)c;
gBoxes.Add(gBoxAux);
}
}
I don't know if there's a better way to do it instead of iterate over all the controls.
Thank you very much!
You can query that using Linq:
this.Controls.OfType<GroupbBox>().Where(x=> x.Name == "SomeName").ToList();
Well to find all groupboxes there is no better way than to iterate over all of them. But (for me) the code would look better with this:
List<GroupBox> gBoxes = this.Controls.OfType<GroupbBox>().ToList();
OfType<T> selects all elements of a sequence that are of that type.
Note that this only finds all groupboxes directly contained in this ControlCollection but not in sub-containers. You may want to collect the groupboxes recursively:
public IEnumerable<GroupBoxes> GetAllGroupBoxes(Control c)
{
return c.Controls.OfType<GroupBox>()
.Concat(c.Controls.OfType<Control>().SelectMany(GetAllGroupBoxes));
}
List<GroupBox> gBoxes = GetAllGroupBoxes(this).ToList();
To filter for a specific name you can use Where:
Controls.OfType<GroupBox>().Where(gb => gb.Name == "whatever")...
I have more than 50 comboboxes on my form that have as items currencies (USD, EUR). Every currency has its own price TextBox.
What I want to do is sum price values based on currencies.
For example, if I have 20 USD I want to get a sum of those 20 price values.
How do I loop through the comboboxes?
You could use the .Text property of the comboboxes, as #AYETY suggested, but I suppose it depends on how you've populated them and if you'd rather use the value rather than the text, etc.
Anyway, you didn't say where the comboboxes are on the form, so if they are placed in containers, you need to recursively search through the controls on your form, e.g.
public IEnumerable<Control> GetChildControls(Control parentControl)
{
List<Control> controls = new List<Control>();
foreach (Control child in parentControl.Controls)
{
controls.AddRange(GetChildControls(child));
}
controls.Add(parentControl);
return controls;
}
and then interrogate the comboboxes. Based off using the Text property of the comboboxes, you could do something like this:
private void SumCurrencies()
{
var controls = GetChildControls(this);
foreach (var control in controls.Where(c => c is ComboBox))
{
if (control.Text == "USD")
{
// do something
}
else if (control.Text == "GBP")
{
// do something
}
else if (control.Text == "EUR")
{
// do something
}
}
}
int i = 0;
foreach (Control c in this.Controls)
{
if (c is ComboBox)
{
if (c.Text == 'USD')
i++;
}
}
how can i remove multiple items from observablecollection in silverlight.in my project i have one datagrid populating more than one items.in every row contain one checkbox also.if i select more than one row by selecting checkbox and click delete button ,i want to delete all the item from the collection.
public void delete(object parameter)
{
foreach (var x in Book)
{
if (x.Ischeck == true)
{
Book.Remove(x);
}
}
}
it cause error.can't change observablecollection
You can use below mentioned code snippet instead:
foreach (var x in Book.ToList())
{
if (x.Ischeck)
{
Book.Remove(x);
}
}
OR
for (int i = Book.Count - 1; i >= 0; i--)
{
if (Book[i].Ischeck)
{
Book.RemoveAt(i);
}
}
I assume that the error message is a bit different. To be more precise, it is:
Collection was modified; enumeration operation may not execute.
To work around this problem, one possible solution is this:
foreach (var itemToRemove in Book.Where(x => x.Ischeck).ToList())
{
Book.Remove(itemToRemove);
}
This will get all items you want to remove and put them into a new list. When you now remove items from Book you are not disturbing the list you are currently iterating over as this is an independent instance.
Using Where before calling ToList reduces the number of references you copy to the new list to only those that really need to be copied.
Simply get a list of the objects contained first:
public void delete(object parameter)
{
foreach (var x in Book.ToList())
{
if (x.Ischeck == true)
{
Book.Remove(x);
}
}
}
The reason for this is that you can't remove elements from an observable collection while you're enumerating the elements. By calling ToList() you enumerate the whole collection first, store it in a list and then check what to remove.
I have a winforms app that has 37 textboxes on the screen. Each one is sequentially numbered:
DateTextBox0
DateTextBox1 ...
DateTextBox37
I am trying to iterate through the text boxes and assign a value to each one:
int month = MonthYearPicker.Value.Month;
int year = MonthYearPicker.Value.Year;
int numberOfDays = DateTime.DaysInMonth(year, month);
m_MonthStartDate = new DateTime(year, month, 1);
m_MonthEndDate = new DateTime(year, month, numberOfDays);
DayOfWeek monthStartDayOfWeek = m_MonthStartDate.DayOfWeek;
int daysOffset = Math.Abs(DayOfWeek.Sunday - monthStartDayOfWeek);
for (int i = 0; i <= (numberOfDays - 1); i++)
{
//Here is where I want to loop through the textboxes and assign values based on the 'i' value
DateTextBox(daysOffset + i) = m_MonthStartDate.AddDays(i).Day.ToString();
}
Let me clarify that these textboxes appear on separate panels (37 of them). So in order for me to loop through using a foreach, I have to loop through the primary controls (the panels), then loop through the controls on the panels. It starts getting complicated.
Any suggestions on how I can assign this value to the textbox?
To get all controls and sub-controls recursively of specified type, use this extension method:
public static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control
{
var children = (control.Controls != null) ? control.Controls.OfType<TControl>() : Enumerable.Empty<TControl>();
return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children);
}
usage:
var allTextBoxes = this.GetChildControls<TextBox>();
foreach (TextBox tb in allTextBoxes)
{
tb.Text = ...;
}
You Could loop all the controls in the form asking one by one if it is a "Textbox" y ther return the complete List of them.
public List GetTextBoxes(){
var textBoxes = new List();
foreach (Control c in Controls){
if(c is TextBox){
textBoxes.add(c);
}
}
return textBoxes;
}
You can loop through the textboxes in your form in a fairly simple manner:
Func<ControlCollection, List<TextBox>> SearchTextBoxes = null;
SearchTextBoxes = coll => {
List<TextBox> textBoxes = new List<TextBox>();
foreach (Control c in coll) {
TextBox box = c as TextBox;
if (box != null)
textBoxes.Add(box);
if (c.Controls.Count > 0)
textBoxes.AddRange(SearchTextBoxes(c.Controls));
}
return textBoxes;
};
var tbs = SearchTextBoxes(this.Controls).OrderBy(tb => tb.Name);
Edit: Changed according to new requirements. Not nearly as elegant as the LINQ-solution, of course :)
Since this post seems to resurrect itself from time to time and since the solutions above do not find controls inside of controls, such as in a groupbox, this will find them. Just add your control type:
public static IList<T> GetAllControls<T>(Control control) where T : Control
{
var lst = new List<T>();
foreach (Control item in control.Controls)
{
var ctr = item as T;
if (ctr != null)
lst.Add(ctr);
else
lst.AddRange(GetAllControls<T>(item));
}
return lst;
}
And it's use:
var listBoxes = GetAllControls<ListBox>(this);
foreach (ListBox lst in listBoxes)
{
//Do Something
}
Iterate through controls within form and check name of the control if matched then set Text property as you require.
int i = 0;
foreach (Control contrl in this.Controls) {
if (contrl.Name == ("DateTextBox" + i.ToString())) {
contrl.Text = "requiredtexttobeset";
}
i = i + 1;
}
If you want to do without 'foreach' (If you have specific boxes to adjust/address)
int numControls = Page.Form.Controls.Count;
for (int i = 0; i < numControls; i++)
{
if (Page.Form.Controls[i] is TextBox)
{
TextBox currBox = Page.Form.Controls[i] as TextBox;
currbox.Text = currbox.TabIndex.ToString();
}
}
//THE EASY WAY! Always post easy solutions. It's the best way.
//This code is used to loop through all textboxes on a form for data validation.
//If an empty textbox is found, Set the error provider for the appropriate textbox.
foreach (var control in Controls)
{
if (control is TextBox)
{
//Box the control into a textbox. Not really needed, but do it anyway
var textbox = (TextBox)control;
if (String.IsNullOrWhiteSpace(textbox.Text))
{
//Set the errorProvider for data validation
errorProvider1.SetError(textbox, "Data Required!");
textbox.Text = String.Empty; //Clear out the whitespace if necessary
//blnError = true;
}
}
}
You can simply do this mate...
foreach (TextBox txt in this.Panel.Controls.OfType<TextBox>())
{
txt.Text="some value you assign";
}
If your text boxes are on the form directly and not on a Panel then you can replace this.Panel.Controls with this.Controls. That should be short and clear enough for you.
After the InitialiseComponents() call, add the textboxes to a collection member variable on the form. You can then iterate through them in order later on.
You can create a Dictionary of TextBox, int like the following
Dictionary<TextBox, int> textBoxes = new Dictionary<TextBox, int>();
foreach (TextBox control in Controls.OfType<TextBox>())
textBoxes[control] = Convert.ToInt32(control.Name.Substring(11));
Now.. to loop through them..
foreach (var item in textBoxes.Select(p => new { textBox = p.Key, no = p.Value}))
item.textBox.Text = item.no.ToString(); // whatever you want...
Good luck!
Since you already know the name of control, therefore you can search the control by its name.
See Get a Windows Forms control by name in C#
Other answers just not cutting it for you?
I found this as an answer to a similar question on SO, but I can't find the thread now. It recursively loops through ALL controls of a given type which are located within a control. So includes children of children of children of... etc. My example changes the ForeColor of each TextBox to Hot Pink!
public IEnumerable<Control> GetAllControlsOfType(Control control, Type type)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAllControlsOfType(ctrl, type))
.Concat(controls)
.Where(c => c.GetType() == type);
}
Implementation:
IEnumerable<Control> allTxtBxs = GetAllControlsOfType(this, typeof(TextBox));
foreach (TextBox txtBx in allTxtBxs)
{
txtBx.ForeColor = Color.HotPink;
}
Quite similar to abatishchev's answer(which, for me, only returned first-level child controls), but different enough to merit it's own answer I think.