CAD
CAD

Reputation: 4292

Listing matching items in a combo box while entering a text?

I have a ComboBox in a form and while the user typing some text in the box, if there are matching items in the database with the text typed, should be listed in the ComboBox. So that the user can be notified if the item being entered is already in the database. I'm trying to achieve this as follows.

When a text is entered in the combo it will fire an event. Listening to that event, Presenter will get matching user list from the database and then the list will be set as the DataSource of the ComboBox as follows...

But why it is not displayed in the combo? Please let me know the issue in this code!

Form

public partial class frmUser : Form
{
    // two seperate get and set properties are used to same combo box as a list will be set as the datasource.

    public string UserName 
    {
        get{return cmbUserName.Text;}
    }

    public IEnumerable<User> UserList
    {
        set { cmbUserName.DataSource = value; }
    }
    private void cmbUserName_TextChanged(object sender, EventArgs e)
    {
        OnChangeText(sender, e);
    }
} 

Presenter

class UserPresenter
{       
    private void WireUpEvents()
    {
        _View.OnChangeText += new EventHandler(_View_OnChangeText);
    }

    private void _View_OnChangeText(object sender, EventArgs e)
    {
        ShowMatchingUsers();
    }

    private void ShowMatchingUsers()
    {
        var userList = _DataService.GetUsers(_View.UserName ); //edit
        _Veiew.UserList = userList; //edit
    }
}

DataService

    public IEnumerable<User> GetUsers(string userID)
    { 
        string selectStatement = "SELECT user_id from [user] WHERE user_id like '@userID %'";
        List<User> UserList = new List<User>();

        using (var sqlConnection = new SqlConnection(db.ConnectionString))

        using (var sqlCommand = new SqlCommand(selectStatement, sqlConnection))
        {
            sqlCommand.Parameters.Add("@userID", SqlDbType.VarChar).Value = userID ;
            sqlConnection.Open();

            using (SqlDataReader dataReader = sqlCommand.ExecuteReader())

                while (dataReader.Read())
                {
                    UserList.Add(
                    new User 
                    {
                        UserID = (string) dataReader["user_id"]
                    });
                }

            return UserList;

        }
    }

Upvotes: 0

Views: 1911

Answers (3)

Mohamed Yunus
Mohamed Yunus

Reputation: 73

use visual studio, set combobox property as follows combobox autocompletemode = SuggestAppend & autocompletesource=ListItems

Upvotes: 1

CAD
CAD

Reputation: 4292

I should have given the value to the parameter as userID+"%" instead of userID. With regard to user listing, I think I have to have a loop adding items to the list somewhere.

Upvotes: 0

TaW
TaW

Reputation: 54433

I can't tell you exactly how to change your code because I am missing quite a few details, like some events and classes and the possible nesting states of your classes and objects.

But the error is, like I noted, the fact that the resulting IEnumerable<User>which GetUsers brings back is thrown away.

You wrote that it should get used as the DataSource of the ComboBox via the Property UserList but in fact you are hiding this property by declaring a new

List<User> UserList = new List<User>();

locally in GetUsers. This would be OK, albeit a little confusing; (I suggest you call it something different like newUserlist ;) but you still need to set the real UserList to the returned result set somewhere!

When I patched this up like this (missing important info on your actual code)

private void cmbUserName_TextChanged(object sender, EventArgs e)
{
  UserList = _DataService.GetUsers("_View.UserName");

   ///OnChangeText(sender, e); re-instate your own wiring!
}

a dummy value showed up fine in the Combobox..

You should not use my code but stay with you set up! Changing

_DataService.GetUsers(_View.UserName );

to

Userlist = _DataService.GetUsers(_View.UserName );

seems to be the direct solution, but you probably will have to watch for a way to connect innner and outer class variables..

Upvotes: 1

Related Questions