[英]Binding an Enum property values to ListView.Items(WinForms)
我有以下實體:
public class MyEntity
{
public int Id {get;set}
public Color SelectedColors
}
MyEntity
與Color
枚舉具有One-to-Many
關系。
[Flags]
public enum Color
{
None=1,
White=2,
Red=3,
Blue=4
}
換句話說,每個myEntity
對象可能具有Color
枚舉中的一個或多個值:
myEntity1.Color = Color.Red | Color.White;
我使用Entity Framewrok
保存了這些數據:
using (var ctx = new MyContext())
{
var entity1 = new MyEntity { SelectedColors = Color.Blue | Color.White };
ctx.MyEntities.Add(entity1);
ctx.SaveChanges();
}
並使用以下代碼閱讀:
using (var ctx = new MyContext())
{
var entity1 = ctx.MyEntities.Find(id);
}
我想顯示所選顏色蜱chechboxes
,
我使用ListView
控件(WinForms項目)來完成此工作:
listView1.CheckBoxes = true;
listView1.HeaderStyle = None;
listView1.View = List;
並使用以下代碼將所有Enum
值顯示為ListView.Items
:
foreach (var value in Enum.GetValues(typeof(Color)).Cast<Color>())
{
listView1.Items.Add(new ListViewItem()
{
Name = value.ToString(),
Text = value.ToString(),
Tag = value
});
}
有什么方法可以將查詢結果的SelectedColors
值綁定到listView1.Items
?
[更新]
我在此鏈接中看到了一個解決方案,即Nick-K從ListView
繼承了一個新控件。 我認為該解決方案對我不好,因為繼承的控件帶有一個DataSource
和一個DataMember
,那么在我的情況下我應該為DataMember
設置什么( SelectedColors
可能有多個值)?
ListView類不支持設計時綁定
看這個
http://www.codeproject.com/Articles/10008/Data-binding-a-ListView
首先,您的枚舉應如下所示:
[Flags]
public enum MyColors
{
None = 0,
White = 1,
Red = 2,
Blue = 4
}
使用此屬性
public List<string> SelectedColorsList
{
get
{
return SelectedColors.ToString()
.Split(new[] { ", " }, StringSplitOptions.None)
.ToList();
}
set
{
if (value == null)
{
this.SelectedColors = MyColors.None;
return;
}
int s = 0;
foreach (var v in value)
{
s += (int)Enum.Parse(typeof(MyColors), v);
}
this.SelectedColors = (MyColors)s;
}
}
如果要編輯顏色,則可以從ListView繼承自己的控件:
public class ColorListControl : ListView
{
public event EventHandler SelectedColorChanged;
private Color selectedColor = Color.None;
[DefaultValue( Color.None )]
public Color SelectedColor
{
get { return selectedColor; }
set
{
if( selectedColor != value )
{
selectedColor = value;
foreach( ListViewItem item in this.Items )
{
Color itemColor = (Color)item.Tag;
if( itemColor == Color.None ) //see http://stackoverflow.com/questions/15436616
item.Checked = value == Color.None;
else
item.Checked = value.HasFlag( itemColor );
}
SelectedColorChanged?.Invoke( this, EventArgs.Empty );
}
}
}
public ColorListControl()
{
this.CheckBoxes = true;
this.HeaderStyle = ColumnHeaderStyle.None;
this.View = View.List;
foreach( Color value in Enum.GetValues( typeof( Color ) ).Cast<Color>() )
{
this.Items.Add( new ListViewItem()
{
Name = value.ToString(),
Text = value.ToString(),
Tag = value
} );
}
}
protected override void OnItemChecked( ItemCheckedEventArgs e )
{
base.OnItemChecked( e );
Color checkedColor = (Color)e.Item.Tag;
if( e.Item.Checked )
SelectedColor |= checkedColor;
else
SelectedColor &= ~checkedColor;
}
}
然后,您可以綁定到其屬性SelectedColor:
public class MainForm : Form
{
private ColorListControl listView1;
public MainForm()
{
InitializeComponent();
MyEntity entity = new MyEntity { SelectedColors = Color.Blue | Color.White };
listView1.DataBindings.Add( nameof( listView1.SelectedColor ), entity, nameof( entity.SelectedColors ) );
}
private void InitializeComponent()
{
this.listView1 = new ColorListControl();
this.SuspendLayout();
//
// listView1
//
this.listView1.Location = new System.Drawing.Point(16, 16);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(200, 128);
this.listView1.TabIndex = 0;
this.listView1.SelectedColorChanged += new System.EventHandler(this.listView1_SelectedColorChanged);
//
// MainForm
//
this.ClientSize = new System.Drawing.Size(318, 189);
this.Controls.Add(this.listView1);
this.Name = "MainForm";
this.Text = "Form";
this.ResumeLayout(false);
}
private void listView1_SelectedColorChanged( object sender, EventArgs e )
{
this.Text = listView1.SelectedColor.ToString();
}
}
正如@MSL已經說過的:您需要以2的冪(0、1、2、4、8、16 ...)定義Color枚舉的數量。 請參閱https://msdn.microsoft.com/library/system.flagsattribute.aspx
要編譯此示例,您需要C#6.0 / Visual Studio2015。否則,必須將nameof( listView1.SelectedColor )
替換為"SelectedColor"
。
除了考慮使用ListView之外,還可以考慮使用CheckedListBox:
public class ColorListControl : CheckedListBox
{
public event EventHandler SelectedColorChanged;
private Color selectedColor = Color.None;
[DefaultValue( Color.None )]
public Color SelectedColor
{
get { return selectedColor; }
set
{
if( selectedColor != value )
{
selectedColor = value;
for( int i = 0; i < this.Items.Count; i++ )
{
Color itemColor = (Color)this.Items[i];
if( itemColor == Color.None )
this.SetItemChecked( i, value == Color.None );
else
this.SetItemChecked( i, value.HasFlag( itemColor ) );
}
SelectedColorChanged?.Invoke( this, EventArgs.Empty );
}
}
}
public ColorListControl()
{
CheckOnClick = true;
foreach( Color value in Enum.GetValues( typeof( Color ) ) )
this.Items.Add( value );
}
protected override void OnItemCheck( ItemCheckEventArgs ice )
{
base.OnItemCheck( ice );
Color checkedColor = (Color)this.Items[ice.Index];
if( ice.NewValue == CheckState.Checked )
SelectedColor |= checkedColor;
else
SelectedColor &= ~checkedColor;
}
}
如果只想查看顏色,則可以僅設置ListViewItem
Checked
-property,而無需任何數據綁定或自定義控件:
foreach (var value in Enum.GetValues(typeof(Color)).Cast<Color>())
{
listView1.Items.Add(new ListViewItem()
{
Name = value.ToString(),
Text = value.ToString(),
Checked = entity1.SelectedColors.HasFlag( value ),
Tag = value
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.