自定义 C# 卡片视图类型控件
Custom C# card view type control
我是初学者,正在用 C# Winforms 程序编写一个问答程序。
从根本上说,我希望能够在一系列 "cards" 中显示问题和答案对。
每张卡片都必须能够显示文本,并通过一两个按钮具有其他功能。
devexpress card view control 看起来有点像我想要的。
但是价格高得让人望而却步。
我不确定答案是否在于制作自定义控件,在 运行 时间为每个数据项复制该控件?
我很感激被指出正确的方向,因为我似乎已经坚持了一段时间,不知道从哪里开始。
dev express 控件是为有钱人准备的,我们穷人可以自己实现!
您必须创建一个 CardsPanel
控件,其中包含 CardViewModel
的集合。它显然会读取集合中的每个项目,为其创建一个 Card
控件,设置它的视图模型并将其添加到 Panel
。你基本上回答了你自己的问题!
至于在该 CardControl 中的平滑移动,它可能需要一些用于添加 Lerp 和 Slerp 的代码,但这应该不会太难。您可以在需要时使用 ObservableCollection
监控对集合的添加。从您的 link 来看,设计似乎非常简单,用普通的 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;
}
}
你可以在这里看到,我在其中放置了一些测试数据,但总体概念就在那里,它是你可以下手的基础。
祝你好运!
我是初学者,正在用 C# Winforms 程序编写一个问答程序。 从根本上说,我希望能够在一系列 "cards" 中显示问题和答案对。 每张卡片都必须能够显示文本,并通过一两个按钮具有其他功能。
devexpress card view control 看起来有点像我想要的。 但是价格高得让人望而却步。
我不确定答案是否在于制作自定义控件,在 运行 时间为每个数据项复制该控件?
我很感激被指出正确的方向,因为我似乎已经坚持了一段时间,不知道从哪里开始。
dev express 控件是为有钱人准备的,我们穷人可以自己实现!
您必须创建一个 CardsPanel
控件,其中包含 CardViewModel
的集合。它显然会读取集合中的每个项目,为其创建一个 Card
控件,设置它的视图模型并将其添加到 Panel
。你基本上回答了你自己的问题!
至于在该 CardControl 中的平滑移动,它可能需要一些用于添加 Lerp 和 Slerp 的代码,但这应该不会太难。您可以在需要时使用 ObservableCollection
监控对集合的添加。从您的 link 来看,设计似乎非常简单,用普通的 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;
}
}
你可以在这里看到,我在其中放置了一些测试数据,但总体概念就在那里,它是你可以下手的基础。
祝你好运!