Index: ChannelsInGroupControl.cs
===================================================================
--- ChannelsInGroupControl.cs	(revision 28034)
+++ ChannelsInGroupControl.cs	(working copy)
@@ -27,6 +27,7 @@
 using TvLibrary.Interfaces;
 using MediaPortal.UserInterface.Controls;
 using TvLibrary.Log;
+using System.Data;
 
 namespace SetupTv.Sections
 {
@@ -69,25 +70,125 @@
 
         UpdateMenuAndTabs();
 
+        listView1.BeginUpdate();
         listView1.Items.Clear();
-        SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof (GroupMap));
 
+        // Create a dictionary of tuning details keyed on channel id.
+        string sql;
+        IDbCommand icmd = Broker.Provider.GetCommand();
+        IDbDataParameter param = icmd.CreateParameter();
+        param.ParameterName = "myidGroup";
+        param.Value = _channelGroup.IdGroup;
+        param.Direction = ParameterDirection.Input;
+        param.DbType = DbType.String;
+        icmd.Parameters.Add(param);
+        sql = "SELECT * FROM tuningdetail WHERE (isTv = true) AND (idchannel IN " +
+              "(SELECT idChannel FROM groupmap WHERE idGroup = ?myidGroup ORDER BY idChannel))";
+        SqlStatement stmt = new SqlStatement(Gentle.Framework.StatementType.Select, icmd, sql);
+        IList<TuningDetail> details = ObjectFactory.GetCollection<TuningDetail>(stmt.Execute());
+        int prevChannel = -1;
+        List<TuningDetail> l = new List<TuningDetail>();
+        Dictionary<int, List<TuningDetail>> d = new Dictionary<int, List<TuningDetail>>();
+        foreach (TuningDetail detail in details)
+        {
+          if (prevChannel != detail.IdChannel)
+          {
+            if (l.Count > 0)
+              d.Add(prevChannel, l);
+            prevChannel = detail.IdChannel;
+            l = new List<TuningDetail>();
+          }
+          l.Add(detail);
+        }
+        if (prevChannel != -1)
+        {
+          d.Add(prevChannel, l);
+        }
+
+        // Create a dictionary of channels keyed on channel id.
+        icmd = Broker.Provider.GetCommand();
+        param = icmd.CreateParameter();
+        param.ParameterName = "myidGroup";
+        param.Value = _channelGroup.IdGroup;
+        param.Direction = ParameterDirection.Input;
+        param.DbType = DbType.String;
+        icmd.Parameters.Add(param);
+        sql = "SELECT * FROM channel WHERE (isTv = true) AND (idChannel IN " +
+              "(SELECT idChannel FROM groupmap WHERE idGroup = ?myidGroup ORDER BY idChannel))";
+        stmt = new SqlStatement(Gentle.Framework.StatementType.Select, icmd, sql);
+        IList<Channel> channels = ObjectFactory.GetCollection<Channel>(stmt.Execute());
+        Dictionary<int, Channel> dChannels = new Dictionary<int, Channel>();
+        foreach (Channel _ch in channels)
+        {
+          dChannels.Add(_ch.IdChannel, _ch);
+        }
+        
+        // read all channel maps for current group.
+        SqlBuilder sb = new SqlBuilder(Gentle.Framework.StatementType.Select, typeof(GroupMap));
         sb.AddConstraint(Operator.Equals, "idGroup", _channelGroup.IdGroup);
         sb.AddOrderByField(true, "sortOrder");
-
-        SqlStatement stmt = sb.GetStatement(true);
-
+        stmt = sb.GetStatement(true);
         IList<GroupMap> maps = ObjectFactory.GetCollection<GroupMap>(stmt.Execute());
 
+        // here we cannot just fill list with channels from channel list because of map.SortOrder
+        List<ListViewItem> items = new List<ListViewItem>();
+        List<TuningDetail> tuningDetails;
+        Channel channel;
         foreach (GroupMap map in maps)
         {
-          Channel channel = map.ReferencedChannel();
-          if (!channel.IsTv)
-          {
-            continue;
+          if (dChannels.TryGetValue(map.IdChannel, out channel))
+          { 
+            bool hasFta = false;
+            bool hasScrambled = false;
+
+            if (d.TryGetValue(channel.IdChannel, out tuningDetails))
+            {
+              foreach (TuningDetail detail in tuningDetails)
+              {
+                if (detail.FreeToAir)
+                {
+                  hasFta = true;
+                }
+                if (!detail.FreeToAir)
+                {
+                  hasScrambled = true;
+                }
+              }
+
+              int imageIndex;
+              if (hasFta && hasScrambled)
+              {
+                imageIndex = 5;
+              }
+              else if (hasScrambled)
+              {
+                imageIndex = 4;
+              }
+              else
+              {
+                imageIndex = 3;
+              }
+
+              ListViewItem item = new ListViewItem(channel.DisplayName, imageIndex);
+              item.Checked = channel.VisibleInGuide;
+              item.Tag = map;
+
+              if (tuningDetails.Count > 0)
+              {
+                item.SubItems.Add(tuningDetails[0].ChannelNumber.ToString());
+              }
+              items.Add(item);
+            }
           }
-          listView1.Items.Add(CreateItemForChannel(channel, map));
         }
+        
+        // first remove our OnItemChecked event handler because we set check state of items when filling the listview, 
+        // so don't need to recheck them immediately
+        listView1.ItemChecked -= listView1_ItemChecked;
+        listView1.Items.AddRange(items.ToArray());
+        listView1.ItemChecked += listView1_ItemChecked;
+        listView1.EndUpdate();
+
         bool isAllChannelsGroup = (_channelGroup.GroupName == TvConstants.TvGroupNames.AllChannels);
         removeChannelFromGroup.Enabled = !isAllChannelsGroup;
         mpButtonDel.Enabled = !isAllChannelsGroup;
@@ -102,50 +203,6 @@
       }
     }
 
-    private ListViewItem CreateItemForChannel(Channel channel, object map)
-    {
-      bool hasFta = false;
-      bool hasScrambled = false;
-      IList<TuningDetail> tuningDetails = channel.ReferringTuningDetail();
-      foreach (TuningDetail detail in tuningDetails)
-      {
-        if (detail.FreeToAir)
-        {
-          hasFta = true;
-        }
-        if (!detail.FreeToAir)
-        {
-          hasScrambled = true;
-        }
-      }
-
-      int imageIndex;
-      if (hasFta && hasScrambled)
-      {
-        imageIndex = 5;
-      }
-      else if (hasScrambled)
-      {
-        imageIndex = 4;
-      }
-      else
-      {
-        imageIndex = 3;
-      }
-
-      ListViewItem item = new ListViewItem(channel.DisplayName, imageIndex);
-
-      item.Checked = channel.VisibleInGuide;
-      item.Tag = map;
-
-      IList<TuningDetail> details = channel.ReferringTuningDetail();
-      if (details.Count > 0)
-      {
-        item.SubItems.Add(details[0].ChannelNumber.ToString());
-      }
-      return item;
-    }
-
     private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
     {
       if (e.Item is ListViewItem)
@@ -196,7 +253,7 @@
         layer.AddChannelToGroup(channel, _channelGroup);
 
         //get the new group map and set the listitem tag
-        SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof (GroupMap));
+        SqlBuilder sb = new SqlBuilder(Gentle.Framework.StatementType.Select, typeof(GroupMap));
 
         sb.AddConstraint(Operator.Equals, "idChannel", channel.IdChannel);
         sb.AddConstraint(Operator.Equals, "idGroup", _channelGroup.IdGroup);
