2009-05-10 28 views
2

私はC#と.NET 3.5を使用してWindowsフォームでListViewコントロールを使用しています。私はこのListViewコントロールに追加しているいくつかの項目を持っています。そして、ユーザーがリスト内の項目をグループ化するさまざまな方法を選択できるようになっている機能があります。ただし、項目が明示的に理由がないため自動的に生成された「デフォルト」グループにダンプされることがあります。ListViewGroupsが正しく動作しない

コードが大きすぎてここに入れることはできませんが、アルゴリズム的に何を行っているのか説明してください。アイテムを含むリストビューで始まっていて、すでにグループを含んでいてもいなくてもよいとします。

  1. すべての項目を循環し、 のGroupプロパティはnullに設定されています。
  2. ListViewのグループを空にする コレクション。
  3. 新しいグループをListViewの グループコレクションに追加します。
  4. すべてのアイテムを循環させ、ListViewのグループ コレクションから取得した値 を使用して グループプロパティを設定します。

コードを踏んで、すべてを観察しました。各アイテムでは、ListViewのGroupコレクションから適切なグループを取得し、アイテムのGroupプロパティを設定しますが、「Default」グループの下にリストされることがあります。

誰もこれを観察したことがありますか、それが起こっている可能性についての理論がありますか?

+0

が、これは予測可能な方法で発生しますか?具体的には、アイテムの特定のテストセットが与えられた場合、常に「デフォルト」グループにダンプされるのは同じアイテムですか?あなたがそのテストセットからアイテムを徐々に削除すると、(まだそこにあるアイテムの)同じアイテムが「デフォルト」にダンプされるのでしょうか、それとも別のアイテムにダンプされますか? – itowlson

+0

はい。パターンを取得したら、それを再現するのは簡単です。 –

+0

私はコードが再現するには大きすぎると認識していますが、振る舞いが再現可能であれば、テストセットに2つの項目があり、そのうちの1つが正しくグループ化され、そのうちの1つがグループ化されません。もしそうなら、グループを追加し、各項目のGroupプロパティを設定するコードと共に、これら2つの項目を投稿できますか?あるいは、「一度パターンを取得すると再現しやすい」と言います。これは、誤ったグループ分けのパターンを特定したことを意味しますか?あなたはそのパターンを記述できますか? – itowlson

答えて

1

これはよく知られておらず、再現できません(下記を参照)。あなたの "グループを更新する"コードに関連するものは何でも投稿できますか?

using System; 
using System.Windows.Forms; 
static class Program { 
    [STAThread] 
    static void Main() { 
     Application.EnableVisualStyles(); 
     ListView lv; 
     Button btn; 

     Form form = new Form { 
      Controls = { 
       (lv = new ListView { Dock = DockStyle.Fill, 
         ShowGroups = true}), 
       (btn = new Button { Dock = DockStyle.Bottom, 
         Text = "Scramblle" }) 
      } 
     }; 
     Random rand = new Random(); 
     for (int i = 0; i < 40; i++) { 
      lv.Items.Add("Item " + i); 
     } 
     btn.Click += delegate { 
      // 1: Cycle through every item and set it's Group 
      // property to null. 
      foreach (ListViewItem item in lv.Items) { 
       item.Group = null; 
      } 
      // 2: Empty the ListView's Groups collection. 
      lv.Groups.Clear(); 
      // 3: Add new Groups to the ListView's Group collection. 
      int groupCount = rand.Next(lv.Items.Count) + 1; 
      for (int i = 0; i < groupCount; i++) { 
       lv.Groups.Add("grp" + i, "Group " + i); 
      } 
      // 4: Cycle through every item and set the Group property 
      // using a value obtained from the ListView's Group collection 
      // via index. 
      foreach (ListViewItem item in lv.Items) { 
       item.Group = lv.Groups[rand.Next(groupCount)]; 
      } 
     }; 
     Application.Run(form); 
    } 
} 
0

これは複数のスレッドで起こっていますか?

グループが消去される前にグループを持つListViewItemsを追加しているようですね。

0

はい...それは私にも起こりました。アイテムを追加する前にグループを設定してください。つまり、コンストラクタに追加するListViewItemを初期化するときに、それが含まれるグループを意味します。そのように働くことになります。

0

はい、私は同様の動作を見てきました。私が従った解決策はコードhereに基づいています。

実際にリストビューに項目を追加するコードで
public partial class ListViewExtended : ListView 
{ 
    private Collection<Dictionary<string, ListViewGroup>> groupTables = new Collection<Dictionary<string,ListViewGroup>>(); 

    public ListViewExtended() 
    { 
     InitializeComponent(); 
    } 

    /// <summary> 
    /// Create groups for each column of the list view. 
    /// </summary> 
    public void CreateGroups() 
    { 
     CreateGroups(false); 
    } 

    /// <summary> 
    /// Create groups for each column of the list view. 
    /// </summary> 
    public void CreateGroups(bool reset) 
    { 
     if (OSFeature.Feature.IsPresent(OSFeature.Themes)) 
     { 
     if (reset) 
     { 
      this.groupTables.Clear(); 
     } 

     for (int column = 0; column < this.Columns.Count; column++) 
     { 
      Dictionary<string, ListViewGroup> groups = new Dictionary<string, ListViewGroup>(); 

      foreach (ListViewItem item in this.Items) 
      { 
       string subItemText = item.SubItems[column].Text; 

       // Use the initial letter instead if it is the first column. 
       if (column == 0) 
       { 
        subItemText = subItemText.Substring(0, 1).ToUpperInvariant(); 
       } 

       if (!groups.ContainsKey(subItemText)) 
       { 
        groups.Add(subItemText, new ListViewGroup(subItemText) { Name = subItemText }); 
       } 
      } 

      this.groupTables.Add(groups); 
     } 
     } 
    } 

    /// <summary> 
    /// Sets the list view to the groups created for the specified column. 
    /// </summary> 
    /// <param name="column"></param> 
    public void SetGroups(int column) 
    { 
     if (OSFeature.Feature.IsPresent(OSFeature.Themes)) 
     { 
     try 
     { 
      this.BeginUpdate(); 
      this.Groups.Clear(); 

      if (column == -1) 
      { 
       this.ShowGroups = false; 
      } 
      else 
      { 
       this.ShowGroups = true; 
       Dictionary<string, ListViewGroup> groups = groupTables[column]; 
       this.Groups.AddRange(groups.Values.OrderBy(g => g.Name).ToArray()); 

       foreach (ListViewItem item in this.Items) 
       { 
        string subItemText = item.SubItems[column].Text; 

        // For the Title column, use only the first letter. 
        if (column == 0) 
        { 
        subItemText = subItemText.Substring(0, 1).ToUpperInvariant(); 
        } 

        item.Group = groups[subItemText]; 
       } 

       groups.Values.ForEach<ListViewGroup>(g => g.Header = String.Format(CultureInfo.CurrentUICulture, "{0} ({1})", g.Name, g.Items.Count)); 
      } 
     } 
     finally 
     { 
      this.EndUpdate(); 
     } 
     } 
    } 
} 

、あなたはこのような何かをしたい:

this.itemsListView.Items.AddRange(items.ToArray()); 
this.itemsListView.CreateGroups(true); 
this.itemsListView.SetGroups(0); // Group by the first column by default. 
関連する問題