Hi,
When users need to select from a large list a dropdownlist is arguably not necessarily the best solution. However using teleriks "SuggestAppend" option it is a user friendly option. I'm faced with a patient list which potentially has a few thousand names. Instead of binding the full list, I'd like to bind a subset based on the users input: load on demand.
So far I managed to get things working. The dropdownlist is populated when the user inputs at least 3 characters. I also enabled "SuggestAppend" on the control. I'm using the Key_Up event like this:
The problem is that the selected value of the dropdownlist does not necessarily reflect the user selection? Somehow it gets the value of the first item of the renewed datasource. I've fixed this with the leave event:
Now, it works but it seems like a lot of code compared to the ASP.Net control...
Is there an easier way to do this?
Regards,
Raoul
When users need to select from a large list a dropdownlist is arguably not necessarily the best solution. However using teleriks "SuggestAppend" option it is a user friendly option. I'm faced with a patient list which potentially has a few thousand names. Instead of binding the full list, I'd like to bind a subset based on the users input: load on demand.
So far I managed to get things working. The dropdownlist is populated when the user inputs at least 3 characters. I also enabled "SuggestAppend" on the control. I'm using the Key_Up event like this:
/// <summary>
/// Load on demand drop down list
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
private
void
ddlPatient_KeyUp(
object
sender, System.Windows.Forms.KeyEventArgs e)
{
//Datasource only changes when user hits a letter
//OrElse e.KeyCode = Keys.Return Then
if
((e.KeyCode >= Keys.A && e.KeyCode <= Keys.Z)) {
//and we have atleast 3 characters
if
(ddlPatient.Text.Length > 2) {
//suspend any further keyboard input, untill we're done
ddlPatient.KeyDown += SuspendKeyboard;
string
txt = ddlPatient.Text;
//update de dropdown datasource based on the user input (from Open Access model)
ddlPatient.DataSource = _context.Patients
.Where(c => c.Naam.StartsWith(txt) || c.GetrouwdeNaam.StartsWith(txt))
.OrderBy(c => c.Naam)
.ThenByDescending(c => c.GeboorteDatum)
.Take(100);
//This should be done when initializing the form
//ddlPatient.DisplayMember = "InfoZoekPatient"
//ddlPatient.ValueMember = "PatientID"
//restore the user input and place the cursor at the and of the text
ddlPatient.Text = txt;
ddlPatient.SelectionStart = txt.Length;
//restore keyboard input
ddlPatient.KeyDown -= SuspendKeyboard;
}
e.Handled =
true
;
e.SuppressKeyPress =
true
;
}
}
/// <summary>
/// Catch any keyboard input and ignore it!
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
private
void
SuspendKeyboard(
object
sender, KeyEventArgs e)
{
e.Handled =
true
;
e.SuppressKeyPress =
true
;
}
The problem is that the selected value of the dropdownlist does not necessarily reflect the user selection? Somehow it gets the value of the first item of the renewed datasource. I've fixed this with the leave event:
/// <summary>
/// When a patient was not selected, but the user enter a search string we need to clean up.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
private
void
ddlPatient_Leave(
object
sender, System.EventArgs e)
{
RadDropDownList ddl = sender;
bool
clear =
true
;
//check if the selected item valuemember equals the ddl text.
if
(ddl.SelectedItem !=
null
) {
Patient pat = ddl.SelectedItem.DataBoundItem;
if
(pat !=
null
) {
if
(ddl.Text.Trim == pat.InfoZoekPatient.Trim)
clear =
false
;
}
}
if
(clear) {
ddl.SelectedIndex = -1;
ddl.Text =
string
.Empty;
ddl.SelectedItem =
null
;
ddl.Update();
}
}
Now, it works but it seems like a lot of code compared to the ASP.Net control...
Is there an easier way to do this?
Regards,
Raoul