将Enum属性值绑定到ListView.Items(WinForms)

时间:2016-10-05 06:47:31

标签: c# winforms data-binding enums

我有以下实体:

public class MyEntity
{
   public int Id {get;set}
   public Color SelectedColors 
}

MyEntityOne-to-Many枚举有Color的关系。

[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
                           });
}

enter image description here

有没有办法将我的查询结果的SelectedColors值绑定到listView1.Items

[更新]

我在this link中看到Nick-K继承了ListView的新控件的解决方案。我认为这个解决方案对我不好,因为继承的控件需要DataSourceDataMember,所以在我的情况下我应该为DataMember设置什么(SelectedColors可能有多个值)?

3 个答案:

答案 0 :(得分:0)

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;
    }
}

答案 1 :(得分:0)

如果您想编辑您的颜色,您可以从ListView继承自己的控件:

portal-setup-wizard.properties

然后你可以绑定到它的属性SelectedColor:

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;
    }
}

正如@MSL已经说过的那样:你需要以2的幂(0,1,2,4,8,16 ......)定义你的Color枚举的数字。见https://msdn.microsoft.com/library/system.flagsattribute.aspx

要编译此示例,您需要C#6.0 / Visual Studio 2015.否则,您必须将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(); } } 替换为nameof( listView1.SelectedColor )

您也可以考虑使用CheckedListBox,而不是使用ListView:

"SelectedColor"

答案 2 :(得分:0)

如果您只想查看颜色,则可以设置Checked - ListViewItem的属性,而无需任何数据绑定或自定义控件:

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
                  });
}