RE: Customised Web Application for Microsoft CRM Online
I've programmed a checklistbox control in ASP.NET (C#) Web Form that displays a number of items from Microsoft CRM Online via LINQ.
List<string> selDropdown = chkMyItemsHere.Items.Cast<ListItem>()
.Where(li => li.Selected)
.Select(li => li.Value)
.ToList();
string ListBoxValues = string.Join(", ", selDropdown);
This works perfectly and I'm able to save the string into one field (i.e. 'string value, string value').
Now, on Page_Load I need to split the values from the combined string and tick the relevant checkboxes in the checkListbox.
string[] k = i.LINQFIELD.Split(',');
for (int m = 0; m <= k.Length - 1; m++)
{
for (int x = 0; x <= chkMyItemsHere.Items.Count; x++)
{
if (chkMyItemsHere.Items[x].Value == k[m])
{
chkMyItemsHere.Items[x].Selected = true;
}
}
}
Any ideas why this wouldn't be re-populating my checkboxlist? Any help would be greatly appreciated.
In your code that works, you have this:
string.Join(", ", selDropdown);
In your code that does not, you have this:
string[] k = i.LINQFIELD.Split(',');
Do you see it?
As a solution, I propose you declare a constant variable like so:
private const string SPLIT_VARIABLE = ", ";
Now you have this:
string.Join(SPLIT_VARIABLE, selDropdown);
and
string[] k = i.LINQFIELD.Split(SPLIT_VARIABLE);
After fixing how you split your comma-delimited string -- as suggested by jp2code to make sure there aren't extraneous spaces in each array element -- you can also use LINQ to select the items in your checkboxlist based on what's in your "k" string array:
(from i in chkMyItemsHere.Items.Cast<ListItem>()
where Array.Exists<string>(k, s => { return i.Value == s; })
select i).ToList().ForEach(i => i.Selected = true);
This way, you don't have to use a nested for loop to select your list items.
Related
I'm after some help with how to query a list and return back the index, but not using Linq. I've seen many example where Linq is used, but the software I'm writing the query into doesn't support Linq. :(
So example to get us going:
List<string> location = new List<string>();
location.add(#"C:\test\numbers\FileName_IgnoreThis_1.jpg");
location.add(#"C:\test\numbers\FileName_IgnoreThis_2.jpg");
location.add(#"C:\test\numbers\FileName_ImAfterThis_3.jpg");
location.add(#"C:\test\numbers\FileName_IgnoreThis_4.jpg");
location.add(#"C:\test\numbers\FileName_ImAfterThis_5.jpg");
So this list will be populated with probably a few hundred records, what I need to do is query the list for the text "ImAfterThis" then return the index number location for this item into a string array but without using Linq.
The desired result would be 2 and 4 being added to the string array.
I was thinking of doing a for loop through the list, but is there a better way to achieve this?
List<int> results = new List<int>();
int i = 0;
foreach (string value in location)
{
if (value.Contains("IAfterThis"))
{
results.Add(i);
Console.WriteLine("Found in Index: " + i);
}
i++;
}
Console.ReadLine();
Thanks in advance.
If you want to get just the first occurrence you could simply use the IndexOf() method.
If you want all occurrences of string "whatever" then a for loop would certainly work for you. For the sake of argument here I've capture the indexes in another list:
string MyString = "whatever";
List<int> indexes = new List();
for (int i = 0; i < location.Count; i++)
{
if (location[i] == MyString)
{
indexes.Add(i);
}
}
I am using C# windows form
I have a List of arrays from a function in a class and I called the function into the form
the function returned a List of arrays, how do i get the value of the arrays?
Here is my List of array code
public List<string[]> getAccounts()
{
List<string[]> account = new List<string[]>();
while (*condition*)
{
string[] users = new string[2];
users[0] = user["firstname"].ToString();
users[1] = user["lastname"].ToString();
account.Add(users);
}
return account;
}
and when i call the function I want to show all the firstname into a listbox as well as the last name into another listbox
for (int i = 1; i <= acc.getAccounts().Count; i++)
{
listBoxFirstname.Items.Add(*all the first name from the list*);
}
Use a lambda expression to iterate through the list and select the first name
account.ForEach(s => listBoxFirstname.Items.Add(s[0]));
Without a lambda expression:
List<string[]> accounts = acc.getAccounts()
for (int i = 1; i < accounts ; i++)
{
listBoxFirstname.Items.Add(account[i][0]);
listBoxLastname.Items.Add(account[i][1]);
}
This should do the job:
List<string> firstNames = account.Select(item => item[0]).ToList();
I think will be better to use SelectMany.
listBoxFirstname.Items.AddRange(acc.getAccounts().SelectMany(item=>item[0]))
AddRange
SelectMany
EDIT:
Sorry, i'm blind, you can do it without Select many - you can just use Select
listBoxFirstname.Items.AddRange(acc.getAccounts().Select(item=>item[0]))
I'm working on an importer that takes tab delimited text files. The first line of each file contains 'columns' like ItemCode, Language, ImportMode etc and there can be varying numbers of columns.
I'm able to get the names of each column, whether there's one or 10 and so on. I use a method to achieve this that returns List<string>:
private List<string> GetColumnNames(string saveLocation, int numColumns)
{
var data = (File.ReadAllLines(saveLocation));
var columnNames = new List<string>();
for (int i = 0; i < numColumns; i++)
{
var cols = from lines in data
.Take(1)
.Where(l => !string.IsNullOrEmpty(l))
.Select(l => l.Split(delimiter.ToCharArray(), StringSplitOptions.None))
.Select(value => string.Join(" ", value))
let split = lines.Split(' ')
select new
{
Temp = split[i].Trim()
};
foreach (var x in cols)
{
columnNames.Add(x.Temp);
}
}
return columnNames;
}
If I always knew what columns to be expecting, I could just create a new object, but since I don't, I'm wondering is there a way I can dynamically create an object with properties that correspond to whatever GetColumnNames() returns?
Any suggestions?
For what it's worth, here's how I used DataTables to achieve what I wanted.
// saveLocation is file location
// numColumns comes from another method that gets number of columns in file
var columnNames = GetColumnNames(saveLocation, numColumns);
var table = new DataTable();
foreach (var header in columnNames)
{
table.Columns.Add(header);
}
// itemAttributeData is the file split into lines
foreach (var row in itemAttributeData)
{
table.Rows.Add(row);
}
Although there was a bit more work involved to be able to manipulate the data in the way I wanted, Karthik's suggestion got me on the right track.
You could create a dictionary of strings where the first string references the "properties" name and the second string its characteristic.
I have a detailcollection collection in which every detail has
code, price, name
And a string with some codes
string codes = "1,2,3";
I know I can get an array using string.Split()
string[] codesarray = codes.Split(',');
But how can I get products not in codes?
// the idea I have, but I would not like to have a loop
for (int i = 0; i < codesarray.Length; i++)
{
detailcollection.Where(x => x.ope_idsku == codesarray[i])
}
I would like something like:
detailcollection.Where(x => x.ope_idsku not in (codesarray))
Selected details collection items which ids are not in codesarray:
detailcollection.Where (x=> !codesarray.Contains(x.ope_idsku))
I am programming a program to search the name from the list and I need to find them even if the keyword is not in front of the names (that's what I mean non-prefix)
e.g. if I my list is the music instruments and I type "guit" to the search textbox.
It should find the names "Guitar, GuitarrĂ³n, Acoustic Guitar, Bass Guitar, ..."
or something like this Longdo Dictionary's search suggestion.
here is my simple and stupid algorithm (that's all I can do)
const int SEARCHROWLIMIT = 30;
private string[] DoSearch(string Input, string[] ListToSearch)
{
List<string> FoundNames = new List<string>();
int max = 0;
bool over = false;
for (int k = 0; !over; k++)
{
foreach (string item in ListToSearch)
{
max = (max > item.Length) ? max : item.Length;
if (k > item.Length) continue;
if (k >= max) { over = true; break; }
if (!Input.Equals("Search")
&& item.Substring(k, item.Length - k).StartsWith(Input, StringComparison.OrdinalIgnoreCase))
{
bool exist = false;
int i = 0;
while (!exist && i < FoundNames.Count)
{
if (item.Equals(FoundNames[i]))
{
exist = true;
break;
}
i++;
}
if (!exist && FoundNames.Count < SEARCHROWLIMIT)
FoundNames.Add(item);
else if (FoundNames.Count >= SEARCHROWLIMIT) over = true;
}
}
}
return FoundNames.ToArray();
}
I think this algorithm is too slow for a large number of names and after several trial-and-error, I decided to add SEARCHROWLIMIT to breaks the operation
And I also think there're some readymade methods that can do that.
And another problem is I need to search music instruments by a category like strings, percussions, ... and by the country of origins. So I need to search them with filter by type and country.
How can I achieve this?
Using LINQ you could write code like this:
var resultSet = products
// filter products by category
.Where(product => product.Category == "strings")
// filter products by origin
.Where(product => product.Origin == "italy")
// filter products whose name contains a word starting with "guit"
.Where(product => (" " + product.Name).Contains(" guit"))
// limit the result set to the first 30 matching products
.Take(30);
If your sets of products is reasonably small, you can use LINQ-to-Objects. Otherwise you should use a database and have a look at LINQ-to-SQL.
One word. Database!
Seriously, if you want to do all these different searches, consider placing your data into a database with a schema that simplifies the categorization issues you are having. Sql Server Express now supports full text search which would be very useful for the kind of search you are trying to perform.
There's a nice blog post here about using FTS with Linq-to-Sql.
static List<string> GetItemsWithWordsStartingWithSubstring(List<string> list, string substring)
{
var query = from str in list
from item in str.Split(' ')
where item.StartsWith(substring, StringComparison.InvariantCultureIgnoreCase)
select str;
return query.ToList();
}
I hope I have read your intiial question properly. This function will return any item from the list that contains a word starting with your substring. More punctuation could be added to the split parameters. Given a list with the following contents:
"abcdef","defabc","def abc","xyz"
A search on "abc" will find "abcdef" and "def abc", but not "defabc".