Having some issues with some of my code that has brought me to a brick wall. Even after searching a few hours I cant seem to get it to work. I am quite new to c# so any advice at all even if it points me in the right direction would be greatly appreciated!
What's odd is that it is correctly looping through the dataset, however when it finds the correct row.ItemArray[0].Equals(changeUserName) it does not continue the code and instead skips past it to the "Change failed" error, wont even show the messagebox!
Basically what I am trying to accomplish is this:
There is a table with 3 Columns. Username Password and Email. Password Column contains Hashed Passwords.
I have a form with 4 labels and 4 text fields:
Username - changeusername Textbox
Current Password - currentpassword Textbox
New Password - newpassword Text box
Confirm New Password - confirmnewpassword Text Box
The user fills these forms in, then hits the Change Password Button, which starts the below function:
(This function should check the value of username text box (and current password once ran through my HashPass Function) and compare them to the values in the dataset. If it finds matching values, It then should change the Password value to the new password value in newpassword Text Box. However it does not do this and I cannot figure out why!)
Note: Some of the code in //And look for matching usernames is commented out as I was just trying to get it to even show a MessageBox once it finds a matching Username. But it would not even do this!
public void changePass(string changeusername, string old, string new1, string confirmnew)
{
string EncryptedPass = HashPass(new1);
//If there is no username
if (changeusername == null)
{
MessageBox.Show("Please Enter Username!");
return;
}
//Confirm new pass must equal confirmnewpassword.
else if (new1 != confirmnew)
{
MessageBox.Show("New Passwords do not match");
}
bool loop = false;
//loop database and update new password
foreach (DataRow row in <nameremoved>stockDataSet.login)
{
//And look for matching usernames
if (row.ItemArray[0].Equals(changeUserName))
{
//row.ItemArray[1] = EncryptedPass;
MessageBox.Show("Change Success");
loop = true;
return;
}
}
//Catch Error if Failure
if (loop == false)
{
MessageBox.Show("Change Failed");
}
}
You can't change a single item inside the item array using the indexer.
This happens because when you try to access the ItemArray property, a copy of the original array is created and returned to your code.
And you change items in this copy not on the original one.
You need to get the item array returned, change it and assign it back to the ItemArray property
foreach (DataRow row in <nameremoved>stockDataSet.login)
{
//And look for matching usernames
if (row.ItemArray[0].Equals(changeUserName))
{
object[] returnedArray = row.ItemArray;
returnedArray[1] = EncryptedPass;
row.ItemArray = returnedArray;
MessageBox.Show("Change Success");
loop = true;
return;
}
}
You can check this behavior looking at the Reference Source of ItemArray
However, I can't understand why you want to use the ItemArray property in this context. You can simply refer to your row/column using the standard syntax or better use the Select method on the DataTable to find your row
DataRow[] found = login.Select($"userName = '{changeUserName}'");
if(found != null && found.Length > 0)
{
found[0]["Password"] = EncryptedPass;
}
Here I assume that your first column is named userName and you second column is named Password (change them to fit your names)
Related
I am using a existing web service which does a postcode search its then stored In a list box the values: "ID", "Text", "Highlight", "Cursor", "Description", "Next". I need to try and access a particular string value which is the ID & Next param and use it for validation later on. When I click on the list box I want the particular data to be taken stored then access the two pieces of information I need. How do I access the information on a particular row of the list box and use that later on?
try
{
int myMaxResultValue = (int)nud_MaxResults.Value;
int myMaxSuggestValue = (int)nud_MaxSuggestions.Value;
findResults = objBvSoapClient.CapturePlus_Interactive_Find_v2_10("Dak4-KZ62-AAdd87-X55", txt_Search.Text, txt_LastId.Text, cb_SearchFor.Text, text_Country.Text, text_LanguagePreference.Text, myMaxResultValue, myMaxSuggestValue);
if (txt_Search.Text.Length <= 2)// if less than two letters are entered nothing is displayed on the list.
{
ls_Output.Items.Clear();// Clear LstBox
ls_Output.Items.Add(String.Format(allDetails, "ID", "Text", "Highlight", "Cursor", "Description", "Next"));
MessageBox.Show("Please enter more than 2 Chars!!");
}
else if (txt_Search.Text.Length >= 3)// if greater than or equal to 3 letters in the search box continue search.
{
// Get Results and store in given array.
foreach (var items in findResults)
{ //Loop through our collection of found results and change resulting value.
ls_Output.Items.Add(String.Format(allDetails, items.Id, items.Text.ToString(), items.Highlight, items.Cursor, items.Description, items.Next));
}
}
}
As a side note your string.Format missing the variables in the string. It should be more like this
int id = 30;
string text = "Hello";
string.Format("This is the ID {0}. Here is some text {1}.", id, text);
The output will be "This is the ID 30. Here is some text Hello.".
To answer your question, you'll have to parse it to pull out the parts you want. You could use regex.split to do this. For example, if it's delimited on space you could do something like this
string[] data = Regex.Split(operation, #"\s+");
Then you can access it like this
string required = data[3];
Using Windows forms, My 'listview' have multiple columns as shown in the picture.
I have been trying to make this txtbox_search to be advanced. When any character, word or number is inserted, i want Some columns of my listview to be traversed to look for the character, word, number and bring up data related to the input.
Like when i enter: txtbox_search.Text = "a"
It should travers column "Name" and fill Listview with data:
entire row that has a name which starts with "a" such as "Anwar"
entire row that has a name which starts with "a" such as "Anas"
so on with entire rows that has a name which starts with "A..."
when i enter: txtbox_search.Text = "1"
It should travers column "ID" and fill Listview with data:
entire row that has a ID which starts with "1" such as "1002"
entire row that has a ID which starts with "1" such as "1112"
so on with entire rows that has a ID which starts with "1..."
so far i have been trying this for 2 days and end up with this much:
private void textBox_DEC_Search_TextChanged(object sender, EventArgs e)
{
foreach(ListViewItem Items in listView_DEC_CustomerList.Items)
{
if(Items.Text == textBox_DEC_Search.Text)
{
listView_DEC_CustomerList.Items.Clear();
listView_DEC_CustomerList.Items.Add(Items);
}
}
if(textBox_DEC_Search.Text == "" || textBox_DEC_Search.Text == string.Empty)
{
CusList Cus = new CusList();
Cus.CustomersList(listView_DEC_CustomerList);
}
}
This code only travers first column and bring up data that matches the inserted ID, only if the Complete ID matches with txtbox_search.Text how can i make this possible? (i want it to be on client side, not from sql/database). Guides and sample code helps will be really appreciated. Thanks.
To distinguish between your 2 criteria you could use the following:
if (textBox_DEC_Search.Text.All(x => Char.IsNumber(x)))
{
Debug.WriteLine("Number");
// search through ID
}
else
{
Debug.WriteLine("Name");
// search through Name
}
It basically checks whether your input is solely numeric.
EDIT:
To check for similarity you cold use String.StartsWith of String.Contains to make the search a little more flexible
to look for the ID or NAME you need to access the subitems!
since ID is your first column check SubItems[0]
if(Items.SubItems[0].Text.StartsWith(textBox_DEC_Search.Text) ||
Items.SubItems[0]Text.Contains(textBox_DEC_Search.Text))
since NAME is your second column check SubItems[1]
if(Items.SubItems[1].Text.StartsWith(textBox_DEC_Search.Text) ||
Items.SubItems[1]Text.Contains(textBox_DEC_Search.Text))
One Problem is this line:
listView_DEC_CustomerList.Items.Clear();
because it will erase the first found result when the second is found.
So if you find 10 matches the previous 9 will be deleted!
I suggest to make first the entire search and then add the results if there are any:
private void textBox_DEC_Search_TextChanged(object sender, EventArgs e)
{
// index is 0 if numeric for ID or 1 if not for NAME
int ind = textBox_DEC_Search.Text.All(x => Char.IsNumber(x)) ? 0 : 1;
List<ListViewItem> matchlist = new List<ListViewItem>();
foreach(ListViewItem Items in listView_DEC_CustomerList.Items)
{
if(Items.SubItems[ind].Text.StartsWith(textBox_DEC_Search.Text) ||
Items.SubItems[ind]Text.Contains(textBox_DEC_Search.Text))
{
matchlist.Add(Items);
}
}
// if you have found something add the all results
if(matchlist.Any())
{
listView_DEC_CustomerList.Items.Clear();
listView_DEC_CustomerList.Items.AddRange(matchlist.ToArray());
}
}
Disclaimer: Although this solution should work I would vote to follow the advice of #RezaAghaei. It is less messy and confusing than directly manipulating the ListView
Instead of using == which looks for an exact match try one of the following (I am assuming 'Text' is the column name in the list containing the name - if not change it to Items.Name (for example)
if you want to search on 'starting with' then try
if (Items.Text.StartsWith(textBox_DEC_Search.Text.Trim())
if you want to search based on the fact that a part of the string should be looked up then try
if (Items.Text.Contains(textBox_DEC_Search.Text.Trim())
You can similarly do for any other column you would like to search on. if you want to make the search case insensitive then use .ToLower() on the string and the column name.
I'm generating a report based on a database table. In the table I have genders saved as either 0 or 1 (male/female). In the report I would like to show the string value rather than showing the numbers. I tried messing with the code, ie.
this.ItemsTableAdapter.Fill(this.InventoryDataSet.Items);
foreach (DataRow row in this.InventoryDataSet.Items.Rows)
{
if (row["gender"].ToString() == "0")
{
row["gender"] = "Male";
}
}
this.reportViewer1.RefreshReport();
However this breaks the report complelty (no data is shown). How can I achieve what I want?
[edit]
I came a little closer to the solution (I think) with this:
this.InventoryDataSet.Items.Columns.Add("genderVerbose", typeof(string));
foreach (DataRow row in this.InventoryDataSet.Items.Rows)
{
if (row["gender"].ToString() == "0")
{
row["genderVerbose"] = "Male";
}
}
However now I get this error when trying to use the field in the report:
Error 2 The Value expression for the text box ‘color’ refers to the
field ‘genderVerbose’. Report item expressions can only refer to
fields within the current dataset scope or, if inside an aggregate,
the specified dataset scope. Letters in the names of fields must use
the correct case.
How about assigning Enum values to the cells? Enum.ToString() by default gives the value name in code as the string. So with:
public enum Gender { Male, Female }
You can just shove those into DataGridView cells and it will show that way. You can test values by
if ((Gender)row["gender"].Value == Gender.Male)
{
// do things...
}
If you need this to be user-selectable, you can use the DataGridViewComboBoxCell.
I am using linq to sql and my Datatable(tbl_final_aut) seems as
and I made a select query in my appliaction as
.cs code
var sel = db.selectdoc(24).ToList();
if (sel.Count == 3)
{
//all doc are uploaded
}
else
{
//
}
on seeming my Datatable we can see that I will go in if condition but I want that if my sel.count=2 or sel.count=1 than I want to show that which groupname or type is not there in my datatable
For example :
if my datatable seems to be
so my condition will go to else and there I want to get my alert box that other 2 groupname is not there like
var sel = db.selectdoc(24).ToList();
if (sel.Count == 3)
{
//all doc are uploaded
}
else
{
//I want in alert that "cover letter and CopyrightTra.. is not present"
}
Store procedure code is
ALTER PROCEDURE dbo.selectdoc
#art_aut_id int
AS
select * from tbl_final_aut where art_aut_id=#art_aut_id
RETURN
As you see actually I have only 3 types as you seen in my 1st datatable that is 1,3,4..I just want to know that if any one type says to be 3rd type is not there or present in table than my sel.count=2 so it will go in else condition and there I have to make some code which says that type 3 or coverletter is required to be upload.what code shall I make over there
error
datatype
string[] groupNames = { "Main Article", "Cover Letter" }; // list all groups
var missingGroups =
groupNames.Except(db.selectdoc(24).Select(d => d.groupname).Distinct());
You can also get all group names from database without hard-coding them in code:
string[] groupNames = db.tablename.Select(d => d.groupname).Distinct().ToArray();
I've got a ListBox(with selectionMode=multiple) and store the selected values in a cookie.
When the user comes back I want to provide him with all the options selected again.
What I do so far: I get all the selected values and store the indices ","-separated in a string in the cookie.
When the user comes back I split the string and loop through all ListItems to select each one again!
but with:
foreach (string str in selectedStr)
{
listbox1.SelectedIndex = Int32.Parse(str);
}
I only get one (random?) selected value.
Can anyone help me to get all the selected values selected again?
maybe even a better solution?
Just try using FindByValue property of Listview as follow...
foreach (string str in selectedStr)
{
if(listbox1.Items.FindByValue(str) != null)
{
listbox1.Items.FindByValue(str).Selected = true;
}
}
You can iterate through your splitted string array, and access the ListBox.Items[] based on the index and set the Selected property to true.
foreach (string str in selectedStr)
{
listbox1.Items[Int32.Parse(str)].Selected = true;
}
Make sure that str is indeed an integer and its in range with Items.Length