EylonM
asked on
Incremental search on arrays or lists
Hi
I have a list of countries in a list box that I want to do an incremental search on. I have a text box above the list box and as I write I want the list of countries to be filter in accordance to the what I have written so far. For each letter typed I could simply set the datasource of the list to the results of a linq to sql statement and redo the linq statement for every letter I type. But, the interface will be used by many users and we want to avoid unnecessary round trips to the sql server.
So, I thought of doing the following:
1. On load, create an array that will hold the name of the country and its id using a linq statement
2. Set the datasource of the list to the array.
3. As I type, use linq to filter the array. This way the filtering would be in memory without the round trips to the sql server.
I am need to know how to define the array properly, getting the list display member and value member connect correctly to the array and using linq to filter the array as I type.
Thanks
I have a list of countries in a list box that I want to do an incremental search on. I have a text box above the list box and as I write I want the list of countries to be filter in accordance to the what I have written so far. For each letter typed I could simply set the datasource of the list to the results of a linq to sql statement and redo the linq statement for every letter I type. But, the interface will be used by many users and we want to avoid unnecessary round trips to the sql server.
So, I thought of doing the following:
1. On load, create an array that will hold the name of the country and its id using a linq statement
2. Set the datasource of the list to the array.
3. As I type, use linq to filter the array. This way the filtering would be in memory without the round trips to the sql server.
I am need to know how to define the array properly, getting the list display member and value member connect correctly to the array and using linq to filter the array as I type.
Thanks
You can try to use List<(Of <(T>)>) Class which represents a strongly typed list of objects that can be accessed by index. It provides methods to search, sort, and manipulate lists. Converty the Linq result into List collection and bind it to dropdownlist. Then search on the List collection based on the text typed in the textbox.
To bind a dropdown list using List,
To bind a dropdown list using List,
protected void BindContries()
{
DropDownList ddlCountries;
List<Country> countryList = new List<Country>();
LINQYourDataContext db = new LINQYourDataContext();
var mCountries = from p in db.Countries
orderby 0
select p;
countryList = mCountries.ToList<Country>();
ddlCountries.DataSource = countryList;
ddlCountries.DataTextField = "CountryName";
ddlCountries.DataValueField = "CountryID";
}
//Here Country is a class with CountryName and CountryID properties.
ASKER
Thanks
Doesn't compile on countryList = mCountries.ToList<Country> ();
Doesn't compile on countryList = mCountries.ToList<Country>
ASKER
The error message more or less:
'System.Linq.IQueryable<An onymousTyp e#1>' does not contain a definition for 'ToList' and the best extension method overload 'System.Linq.Enumerable.To List<TSour ce>(System .Collectio ns.Generic .IEnumerab le<TSource >)' has some invalid arguments
'System.Linq.IQueryable<An
Could you please post the error message? Also have you defined a class named Country ?
ASKER
Yes, I defined a class named Country.
public class Country
{
public int nCountryid;
public string cCountry;
}
public class Country
{
public int nCountryid;
public string cCountry;
}
Hi EylonM;
Try it like this, I think this should work for you.
Fernando
Try it like this, I think this should work for you.
Fernando
public partial class frmChooseCountry : Form
{
dcDataContext db = new dcDataContext();
public frmCountries()
{
InitializeComponent();
}
private void frmMycountriest_Load(object sender, EventArgs e)
{
var myusers = (from c in db.countries
orderby c.country
select new Country
{
cCountry = c.country,
nCountryid = c.countryid,
cLastname = c.lastname
}).ToList();
listBox1.DisplayMember = "cCountry";
listBox1.ValueMember = "nCountryid";
listBox1.DataSource =myusers;
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
var myusers = (from c in listBox1.DataSource as List<Country>
where c.cCountry.Substring(0, Math.Min(textBox1.Text.Length, c.cCountry.Length)) == textBox1.Text
orderby c.lastname
select new
{
cCountry = c.country,
nCountryid = c.countryid,
cLastname = c.lastname
}).ToList();
listBox1.DisplayMember = "cCountry";
listBox1.ValueMember = "nCountryid";
listBox1.DataSource =myusers;
}
}
public class Country
{
public int nCountryid { get; set; }
public string cCountry { get; set; }
public string cLastname { get; set; }
}
ASKER
I get the following error:
(I also tried to remove the where clause - didn't help)
System.ArgumentNullExcepti on was unhandled
Message="Value cannot be null.\r\nParameter name: source"
Source="System.Core"
ParamName="source"
StackTrace:
at System.Linq.Enumerable.Whe re[TSource ](IEnumera ble`1 source, Func`2 predicate)
at MerozOfranManage.Forms.frm Test.textB ox1_TextCh anged(Obje ct sender, EventArgs e) in C:\Clients\Ofran\OfranMana ge\OfranMa nage\Forms \frmTest.c s:line 38
at System.Windows.Forms.Contr ol.OnTextC hanged(Eve ntArgs e)
at System.Windows.Forms.TextB oxBase.OnT extChanged (EventArgs e)
at System.Windows.Forms.TextB oxBase.WmR eflectComm and(Messag e& m)
at System.Windows.Forms.TextB oxBase.Wnd Proc(Messa ge& m)
at System.Windows.Forms.TextB ox.WndProc (Message& m)
at System.Windows.Forms.Contr ol.Control NativeWind ow.OnMessa ge(Message & m)
at System.Windows.Forms.Contr ol.Control NativeWind ow.WndProc (Message& m)
at System.Windows.Forms.Nativ eWindow.De buggableCa llback(Int Ptr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.Unsaf eNativeMet hods.SendM essage(Han dleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.Contr ol.SendMes sage(Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.Contr ol.Reflect MessageInt ernal(IntP tr hWnd, Message& m)
at System.Windows.Forms.Contr ol.WmComma nd(Message & m)
at System.Windows.Forms.Contr ol.WndProc (Message& m)
at System.Windows.Forms.Scrol lableContr ol.WndProc (Message& m)
at System.Windows.Forms.Conta inerContro l.WndProc( Message& m)
at System.Windows.Forms.Form. WndProc(Me ssage& m)
at System.Windows.Forms.Contr ol.Control NativeWind ow.OnMessa ge(Message & m)
at System.Windows.Forms.Contr ol.Control NativeWind ow.WndProc (Message& m)
at System.Windows.Forms.Nativ eWindow.De buggableCa llback(Int Ptr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.Unsaf eNativeMet hods.CallW indowProc( IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.Nativ eWindow.De fWndProc(M essage& m)
at System.Windows.Forms.Contr ol.DefWndP roc(Messag e& m)
at System.Windows.Forms.Contr ol.WmKeyCh ar(Message & m)
at System.Windows.Forms.Contr ol.WndProc (Message& m)
at System.Windows.Forms.TextB oxBase.Wnd Proc(Messa ge& m)
at System.Windows.Forms.TextB ox.WndProc (Message& m)
at System.Windows.Forms.Contr ol.Control NativeWind ow.OnMessa ge(Message & m)
at System.Windows.Forms.Contr ol.Control NativeWind ow.WndProc (Message& m)
at System.Windows.Forms.Nativ eWindow.De buggableCa llback(Int Ptr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.Unsaf eNativeMet hods.Dispa tchMessage W(MSG& msg)
at System.Windows.Forms.Appli cation.Com ponentMana ger.System .Windows.F orms.Unsaf eNativeMet hods.IMsoC omponentMa nager.FPus hMessageLo op(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Appli cation.Thr eadContext .RunMessag eLoopInner (Int32 reason, ApplicationContext context)
at System.Windows.Forms.Appli cation.Thr eadContext .RunMessag eLoop(Int3 2 reason, ApplicationContext context)
at System.Windows.Forms.Appli cation.Run (Form mainForm)
at MerozOfranManage.Program.M ain() in C:\Clients\Ofran\OfranMana ge\OfranMa nage\Progr am.cs:line 35
at System.AppDomain._nExecute Assembly(A ssembly assembly, String[] args)
at System.AppDomain.ExecuteAs sembly(Str ing assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.Hos tingProces s.HostProc .RunUsersA ssembly()
at System.Threading.ThreadHel per.Thread Start_Cont ext(Object state)
at System.Threading.Execution Context.Ru n(Executio nContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHel per.Thread Start()
InnerException:
(I also tried to remove the where clause - didn't help)
System.ArgumentNullExcepti
Message="Value cannot be null.\r\nParameter name: source"
Source="System.Core"
ParamName="source"
StackTrace:
at System.Linq.Enumerable.Whe
at MerozOfranManage.Forms.frm
at System.Windows.Forms.Contr
at System.Windows.Forms.TextB
at System.Windows.Forms.TextB
at System.Windows.Forms.TextB
at System.Windows.Forms.TextB
at System.Windows.Forms.Contr
at System.Windows.Forms.Contr
at System.Windows.Forms.Nativ
at System.Windows.Forms.Unsaf
at System.Windows.Forms.Contr
at System.Windows.Forms.Contr
at System.Windows.Forms.Contr
at System.Windows.Forms.Contr
at System.Windows.Forms.Scrol
at System.Windows.Forms.Conta
at System.Windows.Forms.Form.
at System.Windows.Forms.Contr
at System.Windows.Forms.Contr
at System.Windows.Forms.Nativ
at System.Windows.Forms.Unsaf
at System.Windows.Forms.Nativ
at System.Windows.Forms.Contr
at System.Windows.Forms.Contr
at System.Windows.Forms.Contr
at System.Windows.Forms.TextB
at System.Windows.Forms.TextB
at System.Windows.Forms.Contr
at System.Windows.Forms.Contr
at System.Windows.Forms.Nativ
at System.Windows.Forms.Unsaf
at System.Windows.Forms.Appli
at System.Windows.Forms.Appli
at System.Windows.Forms.Appli
at System.Windows.Forms.Appli
at MerozOfranManage.Program.M
at System.AppDomain._nExecute
at System.AppDomain.ExecuteAs
at Microsoft.VisualStudio.Hos
at System.Threading.ThreadHel
at System.Threading.Execution
at System.Threading.ThreadHel
InnerException:
public partial class frmTest : Form
{
dcDataContext db = new dcDataContext();
public frmTest()
{
InitializeComponent();
}
private void frmTest_Load(object sender, EventArgs e)
{
var kuku = (from c in db.users
orderby c.lastname
select new
{
cLastname = c.lastname,
nUserid = c.userid
}).ToList();
listBox1.DisplayMember = "cLastname";
listBox1.ValueMember = "nUserid";
listBox1.DataSource = kuku;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
var kuku = (from c in listBox1.DataSource as List<myUser>
where c.cLastname.Substring(0, Math.Min(textBox1.Text.Length, c.cLastname.Length))
== textBox1.Text
orderby c.cLastname
select new
{
cLastname = c.cLastname,
nUserid = c.nUserid
}).ToList();
listBox1.DisplayMember = "cLastname";
listBox1.ValueMember = "nUserid";
listBox1.DataSource = kuku;
}
public class myUser
{
public int nUserid { get; set; }
public string cLastname { get; set; }
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
In your original code int the load you create:
var myusers
At the bottom you create:
public class Country
int eh kerpress you write:
var myusers = (from c in listBox1.DataSource as List<Country>
I confused things by changing the names, but do you mean that in your original code you should have written in the key press:
var myusers = (from c in listBox1.DataSource as List<myusers>
(and my code should be var kuku = (from c in listBox1.DataSource as List<kuku>)
like you created in the load or
var myusers = (from c in listBox1.DataSource as List<Country>
where you use the class defined at the end?
(in which my code seems to be like you suggested:
var kuku = (from c in listBox1.DataSource as List<myUser>
where myUser is a class defined at the end.)
var myusers
At the bottom you create:
public class Country
int eh kerpress you write:
var myusers = (from c in listBox1.DataSource as List<Country>
I confused things by changing the names, but do you mean that in your original code you should have written in the key press:
var myusers = (from c in listBox1.DataSource as List<myusers>
(and my code should be var kuku = (from c in listBox1.DataSource as List<kuku>)
like you created in the load or
var myusers = (from c in listBox1.DataSource as List<Country>
where you use the class defined at the end?
(in which my code seems to be like you suggested:
var kuku = (from c in listBox1.DataSource as List<myUser>
where myUser is a class defined at the end.)
ASKER
Oops. Ok, I understand. Nice. I will give it a try.
ASKER
Works! Great! Thanks
I hade to make some changes:
In textBox1_TextChanged I added "Country" after new:
select new Country
{
cCountry = c.cCountry,
nCountryid = c.nCountryid,
}).ToList();
I also saved the original list so when I backspace I can roll bak to the original:
List<Country> OriginalList = new List<Country>();
and
OriginalList = myusers;
Then in textBox1_TextChanged i did the Linq on the OriginalList:
from c in OriginalList as List<Country>
insteaqd of on the datasource of listBox1
I hade to make some changes:
In textBox1_TextChanged I added "Country" after new:
select new Country
{
cCountry = c.cCountry,
nCountryid = c.nCountryid,
}).ToList();
I also saved the original list so when I backspace I can roll bak to the original:
List<Country> OriginalList = new List<Country>();
and
OriginalList = myusers;
Then in textBox1_TextChanged i did the Linq on the OriginalList:
from c in OriginalList as List<Country>
insteaqd of on the datasource of listBox1
public partial class frmTest : Form
{
dcTestDataContext db = new dcTestDataContext();
List<Country> OriginalList = new List<Country>();
public frmTest()
{
InitializeComponent();
}
private void frmTest_Load(object sender, EventArgs e)
{
var myusers = (from c in db.countries
orderby c.country1
select new Country
{
cCountry = c.country1,
nCountryid = c.countryid,
}).ToList();
OriginalList = myusers;
listBox1.DisplayMember = "cCountry";
listBox1.ValueMember = "nCountryid";
listBox1.DataSource = myusers;
}
public class Country
{
public int nCountryid { get; set; }
public string cCountry { get; set; }
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
//listBox1.DataSource
var myusers = (from c in OriginalList as List<Country>
where c.cCountry.Substring(0, Math.Min(textBox1.Text.Length, c.cCountry.Length)) == textBox1.Text
orderby c.cCountry
select new Country
{
cCountry = c.cCountry,
nCountryid = c.nCountryid,
}).ToList();
listBox1.DisplayMember = "cCountry";
listBox1.ValueMember = "nCountryid";
listBox1.DataSource = myusers;
}
}
ASKER
public partial class frmChooseCountry : Form
{
dcDataContext db = new dcDataContext();
Array myCountries = Array.CreateInstance(typeo
Array myCountries2 = Array.CreateInstance(typeo
public frmCountries()
{
InitializeComponent();
}
private void frmMycountriest_Load(objec
{
myusers = (from c in db.countries
orderby c.country
select new
{
c.country,
c.countryid
}).ToArray();
listBox1.DataSource =myusers;
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
myusers = (from c in myusers2
where c.country.ToString().Subst
orderby c.lastname
select new
{
c.country,
c.countryid
}).ToArray();
listBox1.DataSource =myusers;
}
}