Monday, October 22, 2012

Multi Select Listbox "Select All" should select all items in the Listbox.



We got a requirement from our client that, when user clicks on the “All” option from a Silverlight list box, and then all Items from that Listbox should be selected.

Here below are the three scenarios.

·         User Clicks on “All” option to select All Items, then all items in the list to be selected.
·         User can select all items individually using Ctl key, then the option “All” also to be selected, even the user not selects it.

·         If any of the Items got unselected, then “All” option also to be unselected.

Here we are trying to write the logic in List Box Selection Changed event, there is a possibility that we may end in infinite loop, if we are trying to implement it without taking care. As selection and de selection will raise Selection Changed event, we should do something to avoid it.

Even if Selection Changed event logic is having some code to be executed, when user really changes selection, that code will be executed unnecessarily because of our newly added code. So it will create latency and performance will be down.

After some research, I have come up with below solution.

        void LstGeographics_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBox lstBox = sender as ListBox;
            if (lstBox.Tag != null && (bool)lstBox.Tag == false)
            {
                lstBox.Tag = true;
                return;
            }
            SetRegionListBoxSelection((ListBox)sender, e);
      
              DoSomething();
        }


In the above event handler, we are checking for ListBox’s tag property, which we are setting to false, when our code itself changing the selection, without user interaction.
So if it is false, then we can avoid unnecessary execution of the method “Dosomething”


   public void SetRegionListBoxSelection(ListBox lstBox, SelectionChangedEventArgs e)
        {
            try
            {
                if (e.AddedItems.Count == 0 && e.RemovedItems.Count == 0)
                    return;
                if (lstBox.SelectedItems.Count == lstBox.Items.Count - 1)
                {
                    if (!e.AddedItems.Cast<ClassName>().Contains(lstBox.Items.Cast<ClassName>().First()))
                        if (!e.RemovedItems.Cast<ClassName>().Contains(lstBox.Items.Cast<ClassName>().First()))
                        {
                            lstBox.Tag = false;
                            lstBox.SelectAll();
                            return;
                        }
                        else
                        {
                            lstBox.Tag = false;
                            lstBox.SelectedItems.Clear();
                        }
                }

                if (e.AddedItems.Cast<ClassName>().Contains(lstBox.Items.Cast<ClassName>().First()))
                {
                    lstBox.Tag = false;
                    lstBox.SelectAll();
                    return;
                }

                if (lstBox.SelectedItems.Count <= lstBox.Items.Count - 1)
                {
                    lstBox.Tag = false;
                    lstBox.SelectedItems.Remove(lstBox.Items.Cast<ClassName>().First());
                   
                }

            }
            catch (Exception ex)
            {
            }
            lstBox.Tag = true;
        }