I create a customized ListView
that inherited from standard ListView
in .NET
to show an enum
values as its Items
( WinForms
project):
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
is my enum:
[Flags]
public enum ScrapGroup
{
None=0,
M=1,
E=2,
N=4,
H=8
}
when I put the ScrapGroupsListView
to my form, everything is OK and the control has no Items:
But each time I build my project, the ScrapGroup
values add to ScrapGroupsListView.Items
(design-time):
after 1st build:
after 2nd build:
and so on.
Where is the problem?
Instead of constructor try:
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,
});
}
}
Every time you open the form in the VS designer it creates this 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});
This is why your items appear two times. First set from the constructor, second set from InitializeComponent()
.
You can (and should) remove the code from InitializeComponent()
but opening the form in the designer will screw it up again.
To prevent from this you can move the filling code to a separate method and invoke it from the form.
In your control:
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,
} );
}
}
In your form:
public MainForm()
{
InitializeComponent();
scrapGroupsListView1.Fill();
}
As a drawback at this solution you don't see your items in the designer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.