自定义C#卡视图类型控件

时间:2017-07-10 14:21:01

标签: c# winforms cardview

我是初学者,在C#Winforms程序中编写测验程序。 从根本上说,我希望能够在一系列"卡片中显示问题和答案对。 每张卡必须能够显示文本,并具有一两个按钮的其他功能。

devexpress card view control看起来有点像我喜欢的。 但价格令人望而却步。

我不确定答案是否在于制作自定义控件,在运行时为每个数据项复制?

我希望被指向正确的方向,因为我似乎已经暂时停留了一段时间而且不确定从哪里开始。

1 个答案:

答案 0 :(得分:1)

对于有钱人来说,开发快递控制是有的,我们穷人可以实现我们自己!

您必须创建一个CardsPanel控件,其集合为CardViewModel。它显然会读取集合中的每个项目,为其创建Card控件,设置它的viewmodel并将其添加到Panel。你基本上回答了自己的问题!

至于CardControl中的平滑移动,可能需要一些Lerp和Slerp添加的代码,但这不应该太难。您可以在需要时使用ObservableCollection监控集合的添加内容。从您的链接设计看起来非常简单,并且用普通的Winforms模拟起来也不会太难。

这是一个完整的例子:

public class CardsPanel : Panel
{
    const int CardWidth = 200;
    const int CardHeight = 150;

    public CardsViewModel ViewModel { get; set; }

    public CardsPanel()
    {
    }
    public CardsPanel(CardsViewModel viewModel)
    {
        ViewModel = viewModel;
        ViewModel.Cards.CollectionChanged += Cards_CollectionChanged;
    }

    private void Cards_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        DataBind();
    }

    public void DataBind()
    {
        SuspendLayout();
        Controls.Clear();

        for(int i = 0; i < ViewModel.Cards.Count; i++)
        {
            var newCtl = new CardControl(ViewModel.Cards[i]);
            newCtl.DataBind();
            SetCardControlLayout(newCtl, i);
            Controls.Add(newCtl);
        }
        ResumeLayout();
    }

    void SetCardControlLayout(CardControl ctl, int atIndex)
    {
        ctl.Width = CardWidth;
        ctl.Height = CardHeight;

        //calc visible column count
        int columnCount = Width / CardWidth;

        //calc the x index and y index.
        int xPos = (atIndex % columnCount) * CardWidth;
        int yPos = (atIndex / columnCount) * CardHeight;

        ctl.Location = new Point(xPos, yPos);
    }
}

public partial class CardControl : UserControl
{
    public CardViewModel ViewModel { get; set; }

    public CardControl()
    {
        InitializeComponent();
    }
    public CardControl(CardViewModel viewModel)
    {
        ViewModel = viewModel;
        InitializeComponent();
    }

    public void DataBind()
    {
        SuspendLayout();

        tbAge.Text = ViewModel.Age.ToString();
        tbAge.Name = ViewModel.Name;
        pbPicture.Image = ViewModel.Picture;

        ResumeLayout();
    }
}

public class CardsViewModel
{
    public ObservableCollection<CardViewModel> Cards { get; set; }
}

public class CardViewModel
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Bitmap Picture { get; set; }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        cardsPanel1.ViewModel = LoadSomeData();
        cardsPanel1.DataBind();
    }

    private CardsViewModel LoadSomeData()
    {
        ObservableCollection<CardViewModel> cards = new ObservableCollection<CardViewModel>();
        cards.Add(new CardViewModel()
        {
            Age = 1,
            Name = "Dan",
            Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
        });
        cards.Add(new CardViewModel()
        {
            Age = 2,
            Name = "Gill",
            Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
        });
        cards.Add(new CardViewModel()
        {
            Age = 3,
            Name = "Glyn",
            Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
        });
        cards.Add(new CardViewModel()
        {
            Age = 4,
            Name = "Lorna",
            Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
        });
        cards.Add(new CardViewModel()
        {
            Age = 5,
            Name = "Holly",
            Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
        });            
        CardsViewModel VM = new CardsViewModel()
        {
            Cards = cards
        };
        return VM;
    }
}

你可以在这里看到我已经在那里插入了一些测试数据,但总体概念是存在的,它是你可以跳下来的基础。

祝你好运!