2016-10-19 7 views
1

créer un ListView personnalisé qui a hérité de la norme ListView en .NET pour montrer une enum valeurs que son Items (WinForms projet):Changer les ListView.Items personnalisés après chaque build

public class ScrapGroupsListView : ListView 
{ 
    public event EventHandler SelectedColorChanged; 

    private ScrapGroup _selectedGroup = ScrapGroup.None; 

    [DefaultValue(ScrapGroup.None)] 
    public ScrapGroup SelectedScrapGroup 
    { 
     get { return _selectedGroup; } 
     set 
     { 
      if (_selectedGroup != value) 
      { 
       _selectedGroup = value; 
       foreach (ListViewItem item in this.Items) 
       { 
        if (item != null) 
        { 
         if (item.Tag != null) 
         { 
          var itemColor = (ScrapGroup)item.Tag; 
          if (itemColor == ScrapGroup.None) 
           item.Checked = value == ScrapGroup.None; 
          else 
           item.Checked = value.HasFlag(itemColor); 
         } 
        } 
       } 

       if (SelectedColorChanged != null) 
        SelectedColorChanged.Invoke(this, EventArgs.Empty); 
      } 
     } 
    } 

    public ScrapGroupsListView() 
    { 
     this.Items.Clear(); 
     this.CheckBoxes = true; 
     this.HeaderStyle = ColumnHeaderStyle.None; 
     this.View = View.List; 

     foreach (var value in Enum.GetValues(typeof(ScrapGroup)).Cast<ScrapGroup>()) 
     { 
      this.Items.Add(new ListViewItem() 
      { 
       Name = value.ToString(), 
       Text = value.ToString(), 
       Tag = value, 
      }); 
     } 
    } 

    protected override void OnItemChecked(ItemCheckedEventArgs e) 
    { 
     base.OnItemChecked(e); 

     var checkedScrapGroup = (ScrapGroup)e.Item.Tag; 

     if (e.Item.Checked) 
      if (checkedScrapGroup == ScrapGroup.None) 
       SelectedScrapGroup = ScrapGroup.None; 
      else 
       SelectedScrapGroup |= checkedScrapGroup; 
     else 
      SelectedScrapGroup &= ~checkedScrapGroup; 
    } 
} 

ScrapGrouop est mon ENUM:

[Flags] 
public enum ScrapGroup 
{ 
    None=0, 
    M=1, 
    E=2, 
    N=4, 
    H=8 
} 

quand je mets le ScrapGroupsListView à ma forme, tout est OK et le contrôle n'a aucun objet:

enter image description here

Mais chaque fois que je construis mon projet, les ScrapGroup valeurs ajouter à ScrapGroupsListView.Items (temps de conception):

après le 1er construction:

enter image description here

après la construction 2ème:

enter image description here

et ainsi de suite.

Où est le problème?

Répondre

0

Au lieu d'essayer constructeur:

protected override void OnCreateControl() 
    { 
     base.OnCreateControl(); 

     this.Items.Clear(); 
     this.CheckBoxes = true; 
     this.HeaderStyle = ColumnHeaderStyle.None; 
     this.View = View.List; 

     foreach (var value in Enum.GetValues(typeof(ScrapGroup)).Cast<ScrapGroup>()) 
     { 
      this.Items.Add(new ListViewItem() 
      { 
       Name = value.ToString(), 
       Text = value.ToString(), 
       Tag = value, 
      }); 
     } 
    } 
0

Chaque fois que vous ouvrez le formulaire dans le concepteur VS il crée ce code:

private void InitializeComponent() 
{ 
    System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem("None"); 
    System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("M"); 
    System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem("E"); 
    System.Windows.Forms.ListViewItem listViewItem4 = new System.Windows.Forms.ListViewItem("N"); 
    System.Windows.Forms.ListViewItem listViewItem5 = new System.Windows.Forms.ListViewItem("H"); 
    this.scrapGroupsListView1 = new ScrapGroupsListView(); 
    // 
    // scrapGroupsListView1 
    // 
    this.scrapGroupsListView1.CheckBoxes = true; 
    this.scrapGroupsListView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; 
    listViewItem1.StateImageIndex = 0; 
    listViewItem1.Tag = ScrapGroup.None; 
    listViewItem2.StateImageIndex = 0; 
    listViewItem2.Tag = ScrapGroup.M; 
    listViewItem3.StateImageIndex = 0; 
    listViewItem3.Tag = ScrapGroup.E; 
    listViewItem4.StateImageIndex = 0; 
    listViewItem4.Tag = ScrapGroup.N; 
    listViewItem5.StateImageIndex = 0; 
    listViewItem5.Tag = ScrapGroup.H; 
    this.scrapGroupsListView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] { 
    listViewItem1, 
    listViewItem2, 
    listViewItem3, 
    listViewItem4, 
    listViewItem5}); 

Voilà pourquoi vos articles apparaissent deux fois. Premier jeu du constructeur, deuxième jeu de InitializeComponent().

Vous pouvez (et devez) supprimer le code de InitializeComponent() mais en ouvrant la forme dans le concepteur vis à nouveau.

Pour éviter de cela, vous pouvez déplacer le code de remplissage à une méthode distincte et l'appeler de la forme.

Dans votre contrôle:

public ScrapGroupsListView() 
{ 
    this.CheckBoxes = true; 
    this.HeaderStyle = ColumnHeaderStyle.None; 
    this.View = View.List; 
} 

public void Fill() 
{ 
    this.Items.Clear(); 

    foreach(var value in Enum.GetValues(typeof(ScrapGroup)).Cast<ScrapGroup>()) 
    { 
     this.Items.Add(new ListViewItem() 
     { 
      Name = value.ToString(), 
      Text = value.ToString(), 
      Tag = value, 
     }); 
    } 
} 

Dans votre formulaire:

public MainForm() 
{ 
    InitializeComponent(); 

    scrapGroupsListView1.Fill(); 
} 

Comme un inconvénient à cette solution, vous ne voyez pas vos articles dans le concepteur.