dropdownlist items find by partial value - c#

To find an item (and select it) in a dropdownlist using a value we simply do
dropdownlist1.Items.FindByValue("myValue").Selected = true;
How can I find an item using partial value? Say I have 3 elements and they have values "myValue one", "myvalue two", "myValue three" respectively. I want to do something like
dropdownlist1.Items.FindByValue("three").Selected = true;
and have it select the last item.

You can iterate from the end of the list and check if value contains the item (this will select the last item which contains value "myValueSearched").
for (int i = DropDownList1.Items.Count - 1; i >= 0 ; i--)
{
if (DropDownList1.Items[i].Value.Contains("myValueSearched"))
{
DropDownList1.Items[i].Selected = true;
break;
}
}
Or you can use linq as always:
DropDownList1.Items.Cast<ListItem>()
.Where(x => x.Value.Contains("three"))
.LastOrDefault().Selected = true;

You can iterate the items in your list, and when you find the first one whose items's string contains the pattern, you can set its Selected property to true.
bool found = false;
int i = 0;
while (!found && i<dropdownlist1.Items.Count)
{
if (dropdownlist1.Items.ToString().Contains("three"))
found = true;
else
i++;
}
if(found)
dropdownlist1.Items[i].Selected = true;
Or you could write a method (or extension method) that does this for you
public bool SelectByPartOfTheValue(typeOfTheItem[] items, string part)
{
bool found = false;
bool retVal = false;
int i = 0;
while (!found && i<dropdownlist1.Items.Count)
{
if (items.ToString().Contains("three"))
found = true;
else
i++;
}
if(found)
{
items[i].Selected = true;
retVal = true;
}
return retVal;
}
and call it like this
if(SelectByPartOfTheValue(dropdownlist1.Items, "three")
MessageBox.Show("Succesfully selected");
else
MessageBox.Show("There is no item that contains three");

Above mentioned answers are perfect, just there are not case sensitivity proof :
DDL.SelectedValue = DDL.Items.Cast<ListItem>().FirstOrDefault(x => x.Text.ToLower().Contains(matchingItem)).Text

Related

compare the items in list in c#

i want to compare the selecteditem of combobox with the selecteditem of other combobox
for this i have registered all the comboboxes in a list and named it "panel1kilist"
now the problem i am facing is that when there are same items in two comboboxes first the messagebox shows "no mattch found" and then it shows "match found" actually it goes to the else statement of inner loop first and then to if statement kindly help
private void button1_Click(object sender, EventArgs e)
{
bool check = false;
bool check1 = false;[![in this image you can see that there are two same items but message is showing "no match found"][1]][1]
try[![after clicking on ok button of message box showing "no match found" this message box shows up][1]][1]
{
for (int i = 1; i < panel1kilist.Count; i++)
{
for (int j = i + 1; j < panel1kilist.Count; j++)
{
if (panel1kilist[i].SelectedItem.ToString() == panel1kilist[j].SelectedItem.ToString())
{
if (check == false)
{
MessageBox.Show("match found");
}
check = true;
}
else
{
if (check1 == false)
{
MessageBox.Show("no match found");
}
check1 = true;
}
}
}
}
catch (System.NullReferenceException)
{
MessageBox.Show("please fill all the boxes first");
}
}
Your question is not really clear but I still try to give you some help. As mentioned in the comments there are several small issues in your code:
1. The outter for-loop
for (int i = 1; i < panel1kilist.Count; i++)
You define i = 1, which means you skip the very first item in your panel1kilist because lists and arrays start at index 0
2. Use of your bool variables
if (panel1kilist[i].SelectedItem.ToString() == panel1kilist[j].SelectedItem.ToString())
{
if (check == false)
{
MessageBox.Show("match found");
}
check = true;
}
else
{
if (check1 == false)
{
MessageBox.Show("no match found");
}
check1 = true;
}
You define your bool variables before starting your for-loops. So whenever you set your variables check and check1 to true, the if conditions check == false and check1 == false will never return true anymore. So you will never get any message except the very first "Match found" and "no match found".
3. My proposed solution
Make use of the foreach-loop and break the loops once you found a match, after the loops just show the message. Code:
var matchFound = false;
foreach (var combobox in panel1kilist)
{
foreach (var comboboxToMatch in panel1kilist.Skip(1))
{
if (combobox.SelectedItem.ToString() == comboboxToMatch.SelectedItem.ToString())
{
matchFound = true;
// Stops the inner loop in case of a match
break;
}
}
// Stops the outer loop in case of a match
if(matchFound)
{
break;
}
}
if(matchFound)
{
MessageBox.Show("match found");
}

how to check error conditions c#

I have group of conditions like
foreach
{
Condition a
condition b
}
So I am validating the values based on conditions.I am facing the problem: for example I have list of items like {1,2,3,4}. So I have a condition like if item 1 is fail then item 2,3,4 should be fail.
if item 2 is fail then item 3,4 should be fail and so on.
I am trying in below code.
foreach (SagaData item in lstPrm)
{
PriceDetail prevPrice = null;
PriceDetail currentPrice = null;
PriceDetail nextPrice = null;
bool bHasError = false;
int iPriceMasterId = 0;
int iPriceTypeId = 0;
string sMprCurrencyType = null;
string sPublisherCurrencyType = null;
int? iExpirationCalendarId = 0;
string sPRMMessage = string.Empty;
//a) If Change Indicator = C or A and Price = 0.00: Cannot change price value to zero.
if ((item.ChangeIndicator == 'C' || item.ChangeIndicator == 'A') && item.PostingPrice == 0)
{
bHasError = true;
sPRMMessage = "FAILURECannot change price value to zero";
}
//b) If Change Indicator = D and Price > 0.00: Invalid deactivation.
if ((item.ChangeIndicator == 'D') && (item.PostingPrice > 0) && (!bHasError))
{
bHasError = true;
sPRMMessage = "FAILUREInvalid deactivation";
}
so i have if condition a fail for item 1 then how should i keep maintain the error for next iteration.
Thanks for the help. if you want more info plz let me know.
You can go through your Collection with a simple for loop and use an ErrorArray:
bool[] bHasError = new bool[lstPrm.Count];
for (int i = 0; i < lstPrm.Count; i++)
{
...
bHasError[i] = true;
...
}
or you can define bHasError BEFORE the foreach if one error is enough for you to consider.

How to scan through values / rows in DataGridView

this is actually my first time asking. I have tried to search everything but i cant find the answer.
I want to scan through all of the values i have in DataGridView to prevent duplications from the first place. I'm using Access as my database. So far i can only check the selected row then compare it to the textbox. My current form. I need to disable "Add" if the textbox value has a similar item name in all of the data
this is my code. It only affects the selected row. not all of the rows.
string item = dgvInventory.Rows[dgvInventory.CurrentRow.Index].Cells[0].Value.ToString();
if (tbItem.Text == item)
{
btnAdd.Enabled = false;
lblAdd.Text = "Item name cannot be the same";
}
else
{
btnAdd.Enabled = true;
lblAdd.Text = "Accepted";
}
Please help?
I tried to insert a for loop So this is my code now but it only happens on the last rows. What am i missing here? or what mistake did i make
for (int x = 0; x < dgvInventory.Rows.Count; x++)
{
string item = dgvInventory.Rows[x].Cells[0].Value.ToString();
if (tbItem.Text == item)
{
btnAdd.Enabled = false;
lblAdd.Text = "Item name cannot be the same";
}
else
{
btnAdd.Enabled = true;
lblAdd.Text = "Accepted";
}
}
You can do something like this,using a foreachloop on the Rowscollection of the DataGridView:
bool found = false;
foreach (DataGridViewRow dgvr in dgvInventory.Rows)
{
if (tbItem.Text == dgvr.Cells[0].Value.ToString())
{
found = true;
break;
}
}
if (found)
{
btnAdd.Enabled = false;
lblAdd.Text = "Item name cannot be the same";
}
else
{
btnAdd.Enabled = true;
lblAdd.Text = "Accepted";
}
Edit: Note: If this is what's you're looking for, but not complete, I can guide/complete the code
Use :
public void SetUpdatable()
{
var canUpdate = VerifyAllRows(tbItem.Text);
if (canUpdate)
{
btnAdd.Enabled = true;
lblAdd.Text = "Accepted";
}
else
{
btnAdd.Enabled = false;
lblAdd.Text = "Item name cannot be the same";
}
}
Verify all rows:
public bool VerifyAllRows(string pValue)
{
foreach (DataGridViewRow row in dgvInventory.Rows)
{
if (!VerifyRow(row,pValue))
{
return false;
}
}
return true;
}
Verify row:
public bool VerifyRow(DataGridViewRow pRow,string pValue)
{
foreach (DataGridViewCell cell in pRow.Cells)
{
string currentItem = cell.Value.ToString();
if (currentItem == pValue)
{
return false;
}
}
return true;
}

How to do this in c#?

I have a List of MyClass and in the main page I have 10 controls which will display the information about that list of Items. What I want is to check the count of the items in the List and then make the excess controls invisible. Now I'm using this code but is there an easier way of doing this?
if (myList.Count > 0)
{
Control1.MyClassInfo = myList[0];
if (myList.Count > 1)
{
Control2.MyClassInfo = myList[1];
if (myList.Count > 2)
{
// and like that till 10
}
else
{
Control3.Visible = false;
Control4.Visible = false;
// till 10
}
}
else
{
Control2.Visible = false;
Control3.Visible = false;
// till 10
}
}
else
{
Control1.Visible = false;
Control2.Visible = false;
Control3.Visible = false;
// and then till 10
}
Well, just add your controls in a list (ordered).
Something like that
var controlList = new List<Control>{ Control1, Control2, Control3 /*etc*/};
var count = myList.Count;
for (var i = 0; i < controlList.Count; i++) {
controlList[i].Visible = count > i;
}
You could create a list of your controls
List<Control> MyControls = new List<Control>{Control1, Control2,..,Control10};
and then
foreach(var C in MyControls)
C.Visible=false;
for(int i=0; i<myList.Count; i++)
C[i].Visible=true;
EDIT: for the more advanced coders here, this technique is called the Composite Pattern.
Basically, that's it. But you can improve on that basic concept in two ways:
1) use a collection
List<Control> _controls1to10;
Put your controls into that collection and write a method like this:
private void setVisibility(List<Control> _controls, bool visible)
{
foreach (Control c in _controls1to10)
{
c.Visible = visible;
}
}
This will make things easier.
2) use boolean expressions instead of nested ifs, like this:
bool hasElements = myList.Count > 0;
bool hasMoreThan1 = myList.Count > 1;
// ... and so on
This means that you have master switches at the top and use them in the following code. This is a fantasy example to clear the concept but does not apply to your code:
bool isEditable = User.LoggedIn && SystemState.Maintenance == false && item.Count > 0;
editButton.Visible = isEditable;
dropList.Visible = !isEditable;

Sorting a DropDownList?

I'm curious as to the best route (more looking towards simplicity, not speed or efficiency) to sort a DropDownList in C#/ASP.NET - I've looked at a few recommendations but they aren't clicking well with me. this drop down is giving me list in alphabetical order. But I have to sort out randomly.
Note:I do not have control over how the data comes into the DropDownList - I cannot modify the SQL.
public void populateLocationList()
{
DataTable dt_locations = (DataTable)daa_addresses.GetDataByEventLocations(int_eventid);
if (dt_locations != null && dt_locations.Rows.Count > 0)
{
// Populate locations dropdown menu
// Bind locationsList instead of dt_locations
ddl_locations.DataTextField = "Key";
ddl_locations.DataValueField = "Value";
ddl_locations.DataSource = RemoveDuplicateLocations(dt_locations);
ddl_locations.DataBind();
string location = "";
// Set the selection based upon the query string
if (Request.QueryString["loc"] != null)
{
location = Request.QueryString["loc"];
locationLbl.Text = Request.QueryString["loc"];
locationID.Value = "-1";
}
if (dt_locations.Rows.Count == 1)
{
location = ddl_locations.Items[0].Text;
locationLbl.Text = location;
}
// Set location in drop down list
int int_foundlocation = 0;
bool foundLocation = false;
foreach (ListItem lsi_item in ddl_locations.Items)
{
if (lsi_item.Text.ToLower().Trim() == location.ToLower().Trim())
{
int_foundlocation = ddl_locations.Items.IndexOf(lsi_item);
foundLocation = true;
break;
}
}
ddl_locations.SelectedIndex = int_foundlocation;
if (ddl_locations.Items.Count == 1)
{
// Make location label visible.
locationLbl.Visible = true;
ddl_locations.Visible = false;
}
else
{
locationLbl.Visible = false;
ddl_locations.Visible = true;
}
//* defualt location S for short courses *//
if (!IsPostBack && !foundLocation)
{
ListItem s = ddl_locations.Items.FindByText("S");
int index = 0;
if (s != null)
{
index = ddl_locations.Items.IndexOf(s);
}
ddl_locations.SelectedIndex = index;
ddl_locations.DataBind();
}
}
}
I have to sort out randomly.
You'd have to shuffle rows, probably with something close to this code (borrowed from #configurator's answer):
internal static class Extensions
{
internal static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
T[] elements = source.ToArray();
// Note i > 0 to avoid final pointless iteration
for (int i = elements.Length - 1; i > 0; i--)
{
// Swap element "i" with a random earlier element it (or itself)
int swapIndex = rng.Next(i + 1);
yield return elements[swapIndex];
elements[swapIndex] = elements[i];
// we don't actually perform the swap, we can forget about the
// swapped element because we already returned it.
}
// there is one item remaining that was not returned - we return it now
yield return elements[0];
}
}
Assuming that RemoveDuplicateLocations returns a DataTable the binding part of your code should be changed to:
ddl_locations.DataSource = RemoveDuplicateLocations(dt_locations)
.AsEnumerable()
.Shuffle(new Random())
.CopyToDataTable();

Categories