Reset background colour of listview using TextChanged event after search - c#

I have a textbox that I can use to search for items and subitems in a listview. Once matches are found the BG colour of the items changes. This works fine, but when I delete the entry from the textbox the items and subitems still remain highlighted until I enter another search.
I am not sure if it is the event that I am using or if it is a problem with my logic. I want the items to be highlighted dynamically as the user types in the search but if they delete the entry I want the BG colour to change back to white.
private void txtSearchMenu_TextChanged(object sender, EventArgs e)
{
string searchVal = txtSearchMenu.Text.ToLower();
if (searchVal != "")
{
foreach (ListViewItem item in lvMenuItems.Items)
{
foreach (ListViewItem.ListViewSubItem subSearch in item.SubItems)
{
if (subSearch.Text.ToLower().Contains(searchVal) == true)
{
subSearch.BackColor = Color.MediumAquamarine;
}
else
{
subSearch.BackColor = Color.White;
}
}
item.UseItemStyleForSubItems = false;
}
}
}

when I delete the entry from the textbox the items and subitems still remain highlighted until I enter another search
This is because you do nothing if textbox is blank.
Move check for empty string inside foreach like this:
private void txtSearchMenu_TextChanged(object sender, EventArgs e)
{
string searchVal = txtSearchMenu.Text.ToLower();
foreach (ListViewItem item in lvMenuItems.Items)
{
foreach (ListViewItem.ListViewSubItem subSearch in item.SubItems)
{
// move condition here
if (searchVal != "" && subSearch.Text.ToLower().Contains(searchVal) == true)
{
subSearch.BackColor = Color.MediumAquamarine;
}
else
{
subSearch.BackColor = Color.White;
}
}
item.UseItemStyleForSubItems = false;
}
}

As Sintar said:
private void txtSearchMenu_TextChanged(object sender, EventArgs e)
{
string searchVal = txtSearchMenu.Text.ToLower();
if (searchVal != "")
{
foreach (ListViewItem item in lvMenuItems.Items)
{
foreach (ListViewItem.ListViewSubItem subSearch in item.SubItems)
{
if (subSearch.Text.ToLower().Contains(searchVal) == true)
{
subSearch.BackColor = Color.MediumAquamarine;
}
else
{
subSearch.BackColor = Color.White;
}
}
item.UseItemStyleForSubItems = false;
}
}
else
{
foreach (ListViewItem item in lvMenuItems.Items)
{
foreach (ListViewItem.ListViewSubItem subSearch in item.SubItems)
{
subSearch.BackColor = Color.White;
}
}
}
}

Related

Search controls in a flowlayoutpanel c#

I'm trying to create a selection for roomType but why some controls are showing even its not equal on Combobox text here is my code in Combobox
private void cbRoomType_SelectedIndexChanged(object sender, EventArgs e) {
GenerateDynamicUserControl();
foreach (Control c in flowLayoutPanel1.Controls)
{
if (c.GetType() == typeof(CustomerControl))
{
CustomerControl customerControl = (CustomerControl)c;
if (!customerControl.RoomType.ToLower().Contains(cbRoomType.Text.ToLower()))
{
flowLayoutPanel1.Controls.Remove(c);
}
}
}
}
Im expecting to solve my problem
You are committing the cardinal sin of modifying the collection while iterating over it with a foreach.
Add all your matches to a separate list and then remove them afterwards:
private void cbRoomType_SelectedIndexChanged(object sender, EventArgs e) {
GenerateDynamicUserControl();
List<CustomerControl> matches = new List<CustomerControl>();
foreach (Control c in flowLayoutPanel1.Controls)
{
if (c.GetType() == typeof(CustomerControl))
{
CustomerControl customerControl = (CustomerControl)c;
if (!customerControl.RoomType.ToLower().Contains(cbRoomType.Text.ToLower()))
{
matches.Add(c);
}
}
}
foreach(var c in matches) {
flowLayoutPanel1.Controls.Remove(c);
}
}

Remove highlight from ListView items....deselecting

Basically I am writing a simple phone directory. This application has a listview window, a search (text) window and a button to search. Once the user inputs a name in the search window and hit the search button, the program selects and highlight all users corresponding to the search criteria.
No problem….
A unique scenario developed however if the user selects another item in the listview window. The previous items found are/will be still highlighted…
How can I deselect/remove the highlight on the found items whenever/ifever the user select another item immediately after the search?
Below is the code attached to the search button:
Thanks in advance
private void button3_Click(object sender, EventArgs e){
string s = " Search Via Forename";
int result = 0;
int count = 0;
result = string.Compare(textBox1.Text, s);
switch ((result == 0) || (String.IsNullOrEmpty(textBox1.Text))){
case true: MessageBox.Show("Please input forename...");
break;
default: foreach (ListViewItem item in listView1.Items){
if (item.Text.ToLower().StartsWith(textBox1.Text.ToLower())){
item.Selected = true;
item.BackColor = Color.CornflowerBlue;
item.ForeColor = Color.White;
count++;
}else{
item.Selected = false;
item.BackColor = Color.White;
item.ForeColor = Color.Black;
}
}
if (listView1.SelectedItems.Count == 1){
listView1.Focus();
}
textBox1.Text = " Search Via Forename";
textBox1.ForeColor = Color.Silver;
break;
}
}
Before your highlightning code, make a loop through all the items and set their item.Selected to false.
foreach (ListViewItem item in listView1.Items){
if (item.Selected)
item.Selected = false;
}
First removed the selection piece of your code. In fact I would just clear selections all together. The color change that your doing is effectively doing the highlighting for you, so from the information you've provided I don't think its necessary to select them.
private void button3_Click(object sender, EventArgs e){
string s = " Search Via Forename";
int result = 0;
int count = 0;
result = string.Compare(textBox1.Text, s);
switch ((result == 0) || (String.IsNullOrEmpty(textBox1.Text))){
case true: MessageBox.Show("Please input forename...");
break;
default: foreach (ListViewItem item in listView1.Items){
item.Selected = false;
if (item.Text.ToLower().StartsWith(textBox1.Text.ToLower())){
item.BackColor = Color.CornflowerBlue;
item.ForeColor = Color.White;
count++;
}else{
item.BackColor = Color.White;
item.ForeColor = Color.Black;
}
}
if (listView1.SelectedItems.Count == 1){
listView1.Focus();
}
textBox1.Text = " Search Via Forename";
textBox1.ForeColor = Color.Silver;
break;
}
}
Next I would use the selection changed event to detect when a selection was made and clear all the formatting I did.
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (ListViewItem item in listView1.Items)
{
item.BackColor = Color.White;
item.ForeColor = Color.Black;
}
}
You didn't specify win forms or WPF so I assumed win forms and made an example that way. If your using WPF i believe the event you would need to subscribe to is the OnSelectionChanged event for the list view control.
After looking at the code a bit more, I realize your using a switch statement to handle a Boolean operation which is not correct. I've added how I would have changed that check below.
private void button3_Click(object sender, EventArgs e)
{
string s = " Search Via Forename";
int result = 0;
int count = 0;
result = string.Compare(textBox1.Text, s);
// Do the check on the input
if ((result == 0) || (string.IsNullOrEmpty(textBox1.Text)))
{
MessageBox.Show("Please input forename...");
// after notifying the user just return
return;
}
foreach (ListViewItem item in listView1.Items)
{
item.Selected = false;
if (item.Text.ToLower().StartsWith(textBox1.Text.ToLower()))
{
item.BackColor = Color.CornflowerBlue;
item.ForeColor = Color.White;
count++;
}
else
{
item.BackColor = Color.White;
item.ForeColor = Color.Black;
}
}
if (listView1.SelectedItems.Count == 1)
{
listView1.Focus();
}
}

'tag_label.visibility' is set to false for some unknown reason

Below is event handler to be executed when a key is pressed ('enter'). No matter where I mention the statement 'p.tag_label.Visibilty=true" in the code,it never shows the tag_label control. Please guide. I mentioned in the code where exactly the tag_label loses its visibilty.
void tag_box_KeyPress(object sender, KeyPressEventArgs e)
{
int i = (sender as TextBox).TabIndex;
if (e.KeyChar == (char)13)
{
foreach (var h in heading_wise)
{
foreach (var p in h.project_panels)
{
if (p.tag_box.TabIndex==i)
{
p.tag_text = p.tag_box.Text;
p.tag_box.Visible = false;
// p.tag_label.Visible = true;
if (!string.IsNullOrWhiteSpace(p.tag_box.Text))
{
p.tag_label.Text = p.tag_box.Text;
p.tag_label.Visible = true;
foreach (Label l in flowLayoutPanel1.Controls)
{
if (l.Text==p.tag_label.Text)
{
continue;
}
else
{
flowLayoutPanel1.Controls.Add(p.tag_label);
// Somewhere here the tag_label loses its visibilty automatically.
}
}
}
}
}
}
}
}

Hide all rows that do not match driverNo.Text

I want to hide all rows in datagrid which do not match the text in driverNo.Text, but when driverNo.Text is null, I'd like all the rows in datagrid to appear. How would I accomplish this?
private void driverNo_KeyUp(object sender, KeyEventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[1].Value.ToString() == driverNo.Text)
{
}
else if (row.Cells[1].Value.ToString() == null)
{
}
}
}
This should solve the problem:
CurrencyManager manager = (CurrencyManager)BindingContext[dataGridView1.DataSource];
manager.SuspendBinding();
bool shouldNotFilter = string.IsNullOrEmpty(driverNo.Text);
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (shouldNotFilter)
{
row.Visible = true;
}
else
{
if (!string.Equals(row.Cells[1].Value.ToString(), driverNo.Text, StringComparison.OrdinalIgnoreCase))
{
row.Visible = false;
}
else
{
row.Visible = true;
}
}
}
manager.ResumeBinding();
This approach is straight forward but slow, I'd suggest you take a look at DataView and its RowFilter property. Here is a good example.
This may not be exactly what you need, but something along these lines?
private void driverNo_KeyUp(object sender, KeyEventArgs e)
{
// Set all rows.Visible = false in design
if (driverNo.Text = "")
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
row.Visible = true;
}
}
else
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[1].Value.ToString() == driverNo.Text)
{
row.Visible = true;
}
}
}
}
This will make all rows visible if the driverNo.Text is null and only show the rows with what is contained in driverNo.Text otherwise.
NOTE: The rows need to not be visible to start, or you can make them visible to start and just change the if statement to != driverNo.Text and set to false

C# Iterate Over DataGridView & Change Row Color

I have a datagridview made up of multiple rows and columns.
I want to iterate through each row and check the contents of a specific column.
If that column contains the word "NO", I want to change the forecolor of the entire row to Red.
Here is an attempt at some code so far but It's certainly not working, starting to wonder If I need to iterate over every cell?
CODE:
foreach (DataGridViewRow dgvr in dataGridView1.Rows)
{
if (dgvr.Cells["FollowedUp"].Value.ToString() == ("No"))
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
}
hook up OnRowDataBound event then do stuff
ASPX (Grid):
<asp:.... OnRowDataBound="RowDataBound"..../>
Code Behind:
protected void RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowIndex == -1)
{
return;
}
if(e.Row.Cells[YOUR_COLUMN_INDEX].Text=="NO"){
e.Row.BackColor=Color.Red;
}
}
FOR WinForms:
hook the **DataBindingComplete** event and do stuff in it:
private void dataGridView1_DataBindingComplete(object sender,
DataGridViewBindingCompleteEventArgs e)
{
if (e.ListChangedType != ListChangedType.ItemDeleted)
{
DataGridViewCellStyle red = dataGridView1.DefaultCellStyle.Clone();
red.BackColor=Color.Red;
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (r.Cells["FollowedUp"].Value.ToString()
.ToUpper().Contains("NO"))
{
r.DefaultCellStyle = red;
}
}
}
}
On your DataGridView, handle the CellFormatting event:
dataGridView1.CellFormatting += new DataGridViewCellFormattingEventHandler(dataGridView1_CellFormatting);
Your event handler could then look like this:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if(dataGridView1.Columns[e.ColumnIndex].Name == "FollowedUp" && e.Value != null && e.Value.ToString() == "No")
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.Red;
}
In this way you aren't 'iterating' over the rows -- simply changing the color with which they are painted/drawn when they become visible (and thus require formatting) in the grid.
public void ColourChange()
{
DataGridViewCellStyle RedCellStyle = null;
RedCellStyle = new DataGridViewCellStyle();
RedCellStyle.ForeColor = Color.Red;
DataGridViewCellStyle GreenCellStyle = null;
GreenCellStyle = new DataGridViewCellStyle();
GreenCellStyle.ForeColor = Color.Green;
foreach (DataGridViewRow dgvr in dataGridView1.Rows)
{
if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("No"))
{
dgvr.DefaultCellStyle = RedCellStyle;
}
if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("Yes"))
{
dgvr.DefaultCellStyle = GreenCellStyle;
}
}
}
Is it possible there are spaces or some other character as part of the cell value? If so try using the Contains method rather than straight equality.
if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("No"))
This is the solution for Winforms:
private void HighlightRows()
{
DataGridViewCellStyle GreenStyle = null;
if (this.dgridv.DataSource != null)
{
RedCellStyle = new DataGridViewCellStyle();
RedCellStyle.BackColor = Color.Red;
for (Int32 i = 0; i < this.dgridv.Rows.Count; i++)
{
if (((DataTable)this.dgridv.DataSource).Rows[i]["col_name"].ToString().ToUpper() == "NO")
{
this.dgridv.Rows[i].DefaultCellStyle = RedCellStyle;
continue;
}
}
}
}
This code works fine for me:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if ((string)row.Cells["property_name"].Value == UNKNOWN_PROPERTY_NAME)
{
row.DefaultCellStyle.BackColor = Color.LightSalmon;
row.DefaultCellStyle.SelectionBackColor = Color.Salmon;
}
}
Other than casting as a string rather than calling ToString I dont really see any difference so it could be a case sensitivity bug. Try using:
dgvr.Cells["FollowedUp"].Value.ToString().ToUpper() == "NO"
private void Grd_Cust_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
colorCode == 4 ? Color.Yellow : Color.Brown;
if (e.RowIndex < 0 || Grd_Cust.Rows[e.RowIndex].Cells["FollowedUp"].Value == DBNull.Value)
return;
string colorCode = Grd_Cust.Rows[e.RowIndex].Cells["FollowedUp"].Value.ToString();
e.CellStyle.BackColor = colorCode == "NO" ? Color.Red : Grd_Cust.DefaultCellStyle.BackColor;
}

Categories

Resources