How to get first selected item in an asp:ListBox w

2019-04-16 13:28发布

问题:

In asp.net if you define an asp:ListBox as follows:

<asp:ListBox ID="listBox2" runat="server" SelectionMode="Single" Rows="3">
  <asp:ListItem>1</asp:ListItem>
  <asp:ListItem>2</asp:ListItem>
  <asp:ListItem>3</asp:ListItem>
  <asp:ListItem>4</asp:ListItem>
  <asp:ListItem>5</asp:ListItem>
  <asp:ListItem>6</asp:ListItem>
  <asp:ListItem>7</asp:ListItem>
  <asp:ListItem Selected="True">8</asp:ListItem>
  <asp:ListItem>9</asp:ListItem>
  <asp:ListItem>10</asp:ListItem>
</asp:ListBox>

You will see that the selected item is visible at the top. But if you define it as a multiple selection list box, the selected items are not visible, and you have to scroll down the list to find them.

<asp:ListBox ID="listBox1" runat="server" SelectionMode="Multiple" Rows="3">
  <asp:ListItem>1</asp:ListItem>
  <asp:ListItem>2</asp:ListItem>
  <asp:ListItem>3</asp:ListItem>
  <asp:ListItem>4</asp:ListItem>
  <asp:ListItem>5</asp:ListItem>
  <asp:ListItem>6</asp:ListItem>
  <asp:ListItem>7</asp:ListItem>
  <asp:ListItem Selected="True">8</asp:ListItem>
  <asp:ListItem Selected="True">9</asp:ListItem>
  <asp:ListItem>10</asp:ListItem>
</asp:ListBox>

I've done a bit of google searching, and see that this is not an uncommon problem. But I did not find any good solutions, so thought I would ask here.

My first thought was to try a bit of JQuery to solve this. What are some of your solutions?

Several of the answers don't even understand my problem. I only care about ensuring that the first selected option is visible. Make sure it is scrolled into view.

I played around with JQuery, and came up with the following:

<script type="text/javascript">
$(document).ready(function() {
   $("#listBox1 option:nth-child(8)").attr('selected',true);
 });
</script>

But I think I like @Cerebrus's answer the best.

回答1:

Here's how I've done it in the past. Note that this scrolls the view to the last item in the listbox.

function FocusSelected()
{
  var lb = document.getElementById("listBox1");
  if (lb != null)
  {
    var options = lb.options;
    for (var i = options.length - 1; i > 0 ; i--)
    {
      if (options[i].selected == true)
      {
        options[i].focus();
        options[i].selected = true;
        return;
      }
    }
  }
}

It works for me on IE 7 and FF 3.0.



回答2:

How are you looking to call this?

From Javascript:

<script type="text/javascript">

var myselect=document.getElementById("listBox1")
for (var i=0; i<myselect.options.length; i++){
    if (myselect.options[i].selected==true){
        alert("Selected Option's index: "+i)
        break;
    }
}

From the Code Behind:

foreach (ListItem li in listBox1.Items)
{
    if (li.Selected)
    {
        return li;
    }
}


回答3:

It's bit clumsy, but I've done this once, and would welcome a better solution.

        //get the selected value
        var selected = (from l in lstFilterUsers.Items.Cast<ListItem>()
                 orderby l.Value
                where l.Selected == true
                select l).Take(1);
        //get all the values except for that first selection
        var all = (from l in lstFilterUsers.Items.Cast<ListItem>()
                   where l != selected
                 orderby l.Value
                 select l);
        //create a temp array and fill it
        ListItem[] lic = new ListItem[lstFilterUsers.Items.Count];
        lic[0] = (ListItem)selected;
        int i = 1;
        foreach (var li in all)
        {
            lic[i++] = li;
        }
        //clear the listbox
        lstFilterUsers.Items.Clear();
        //readd the list
        lstFilterUsers.Items.AddRange(lic);


回答4:

In my limited experimentation, both Chrome and Firefox do the scrolling automatically.

For IE, I cooked this hacky bit of jQuery code up (tested on IE7):

$(document).ready(function(){
    scrollToFirstSelection('select');       
});

function scrollToFirstSelection(query) {
    var select = $(query);
    var singleOption = select.find('option')[0];
    var heightOfSingleOption = select[0].offsetHeight / select.attr('size');
    var indexOfFirstSelection = select.find('option').index($('option[selected=true]:first'));
    select[0].scrollTop = heightOfSingleOption * indexOfFirstSelection;
}

It might not be exact if you use any crazy padding or margins, but it should be close enough.



回答5:

I modified the code so as to get consistent result in both IE and FF, using scrollTo dependency for FF :

 $('select').each(function () {

        var options = $(this).find('option');
        for (var i = options.length - 1; i > 0; i--) {
            if (options[i].selected == true) {

                var x = options[i];                

                if (jQuery.browser.msie) {
                    x.focus();
                    x.selected = true;
                } else {
                    $(x).parents('select:eq(0)').scrollTo(x, 0);
                }

                return;
            }
        }
    });


回答6:

I've found that one line of client-side jQuery code solves this issue. For a multi-select listbox that arrives at the client with one or more selected options, use the power of selectors to find the first selected option. For some reason, simply calling focus() alone doesn't work, but resetting the selected to selected again will then have it scroll the selected element into view.

$(document).ready(function () {

  // Scroll to **FIRST** selected option in multi select list
  $("#lstCountries option:selected(:first)").focus().prop('selected', 'selected');

  // Scroll to **LAST** selected option in multi select list
  $("#lstStates option:selected").focus().prop('selected', 'selected');


});