Load on demand

2 posts, 1 answers
  1. Raoul
    Raoul avatar
    33 posts
    Member since:
    Apr 2012

    Posted 23 Jan 2013 Link to this post

    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:
    /// <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
  2. Answer
    Peter
    Admin
    Peter avatar
    1148 posts

    Posted 24 Jan 2013 Link to this post

    Hello Raoul,

    Thank you for the question.

    This scenario is not typical for RadDropDownList. RadDropDownList is virtualized control and a few visual items (for example 5 - 8) represents many logical items.

    In the AutoComplete pop-up we are using the
    Filter property to filter all items to the items that starts with the text in the editable portion of the DropDownList - you can try to use the Filter property instead of the rebinding the whole DataSource.

    On the other hand your solution looks finished and tailored for the control. 

    You can send this to our
    code library so other customers can benefit from this solution. 

    I hope this answered your question.

    Regards,
    Peter
    the Telerik team
    Q3'12 SP1 of RadControls for WinForms is out now. See what's new.
  3. UI for WinForms is Visual Studio 2017 Ready
Back to Top