0

I have a ListBox that contains all the online users. The users are loaded from a MySQL database and loaded into the ListBox every second. When I add an Item to the ListBox the ListBox scrolls up, I do not want this to happen.

       <asp:UpdatePanel ID="usersPanel" UpdateMode="Conditional" runat="server">
        <ContentTemplate>
          <asp:ListBox ID="lstUsers" runat="server" ViewStateMode="Enabled" AutoPostBack="True"></asp:ListBox>
          <asp:Timer ID="mainTimer" runat="server" ontick="Timer1_Tick" Interval="1000"></asp:Timer>
        </ContentTemplate>
       </asp:UpdatePanel>

Timer Code:

    protected void Timer1_Tick(object sender, EventArgs e)
    {
            ...
            MySqlDataReader datareader = command.ExecuteReader();
            if (datareader.HasRows) {
            lstUsers.Items.Clear();
            while (datareader.Read()) {
                    lstUsers.Items.Add(new ListItem(datareader.GetString(1), datareader.GetInt32(0).ToString()));}
            }
    }

I've tried to do it with javascript but I was unable to get/set the scrollbar position on the listbox

krtek
  • 265
  • 5
  • 15

2 Answers2

1

What is done here is to save the current selected on list on client side, and set it back after the panel have been updated with the new values.

<script type="text/javascript" language="javascript" >
    var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_beginRequest(beighnloadinf);        
    prm.add_endRequest(EndRequest);

    var selected = "";
    //get selected index and store in variable
    function beighnloadinf() {
     var sel = document.getElementbyId('<%=lstUsers.ClientID%>');
     var listLength = sel.options.length;
         for(var i=0;i<listLength;i++){
                 if(sel.options[i].selected){
                     selected =sel.options[i].value;
                     break;
                 }
         }
    }

    // set selected index back afrer update finished
    function EndRequest(sender, args) {
     var sel = document.getElementbyId('<%=lstUsers.ClientID%>');
            sel.value = selected;
    }

</script>

You can do the same thing and on code behind, you get the selected one, and place it after the new update of your list.

Aristos
  • 66,005
  • 16
  • 114
  • 150
Anant Dabhi
  • 10,864
  • 3
  • 31
  • 49
0

You shouldn't be clearing the control every second. This is your problem:

lstUsers.Items.Clear();

Simplest solution would be to compare you ListBox items with your data source using the Except method on IEnumerable.

You'll have to convert your data source to IEnumerable manually. See this post as to how to do that.

NOTE: You'll have to change the type for the extension method.

After that, you can loop through your difference set (the returned object for .Except()) and add them to your list box like this:

lstUsers.Items.Add("a new list item");
Community
  • 1
  • 1
  • If I do not do a clear, and just add items every second (which results in duplicates) the scrollbar is reset also. – krtek Sep 01 '12 at 21:09
  • Get The IEnumerable of your list items in your control like this: var listOfControlItems = lstUsers.Items.Cast().Select(f => f.Text).AsEnumerable() Implement IEnumerable for your MySqlDataReader like in the post (make sure it's of type IEnumerable), push it in to a variable, give it a name, let's call it listFromDB for ease of explanation. get the new items like this: var listOfItemsToAddToControl = listFromDB.Except(listOfControlItems); add them to your control like this: foreach(var item in listOfItemsToAddToControl) { lstUsers.Items.Add(new ListItem(item)); } – Matt Ferron Sep 01 '12 at 22:06
  • To be honest, if I were you I'd be looking at data binding your listbox (select) on the client. – Matt Ferron Sep 01 '12 at 22:44
  • This type of thing will give you the client behaviour you require: $(document).ready(function () { var cursor = 0; setInterval(function () { $('[id$=lstUsers]').append(''); cursor++; }, 10); }); – Matt Ferron Sep 01 '12 at 22:45
  • 1
    You just need to think about getting your data to your client efficiently as json. You could query a web service for the database list and compare against the control list (in javascript), adding new items to the control as demo'd in the snippet above (swapping out the interval for a loop, etc). – Matt Ferron Sep 01 '12 at 22:50