使用 Windows 窗体数据控件和 DataTable 完成画廊类型的显示? [英] Accomplish gallery-type display with a Windows Forms data control and DataTable?
问题描述
我有一个 datatable
,如下所示:
I have a datatable
that looks like the following:
Room Cook Waiter BG_Image
----------------------------------
201 Joe Jim Green.png
202 Jack Mary Red.png
203 Jet Mark Yellow.png
204 Bob Bing Green.png
205 Jack Mary Red.png
206 Jane Burt Red.png
207 Tina Mark Green.png
208 Bob Jill Green.png
我需要将此数据绑定到某种类型的数据控件,以便最终结果如下所示:
I need to bind this data to some type of data control, so that the end-result looks like this:
昨天和今天我一直在尝试使用 dataGridView
寻找解决方案,但还没有成功.
Yesterday and today I've been trying to find a solution using the dataGridView
, but no luck yet.
具有讽刺意味的是,我在 asp.net 网络表单中做了同样的事情,使用 DataList
更容易.但是对于 WinForm,这是一项更加困难的任务.
Ironically, I did the same exact thing in an asp.net webform, and it was much easier with a DataList
. But with a WinForm, it's been a much more difficult task.
所以我的问题是:我可以在 Windows 窗体中使用什么数据控件来绑定到包含的 datatable
以便最终结果类似于我发布的图像?
So my question: what data control can I use in a Windows Form to bind to the included datatable
so that the end-result is something similar to the image I posted?
我不是在寻求问题的解决方案,我只是在寻找朝着正确方向前进的动力.
I'm not asking for a solution to the problem, I'm just looking for a push in the right direction.
(如果问题不是很好,请告诉我,我会尝试更改它.如果太模糊,那是因为我没有什么具体的补充.)
(If the question is not well-formed, please let me know and I'll try to change it. And if it's too vague, it's because I have nothing concrete to add.)
推荐答案
克隆你的设计并不难;并使用某种 DataBinding
到您的 DataTable
来显示数据可以通过一些解决方法来实现.
Cloning your design is not hard; and using some sort of DataBinding
to your DataTable
to display the data can be achieved with a little workaround.
事情会变得更棘手,请阅读:需要更多的努力,当您想要更多而不仅仅是显示数据时.我不会在这里讨论.
Things will get trickier, read: need more effort, when you want more than simply displaying the data. I will not go into that here.
这是一个小例子:
下面的代码只允许您显示数据.没有提供您可以从 DataBinding
获得的任何高级功能,例如导航、编辑、验证..
The code below only lets your display the data. There is no provision for any of the advanced functionality you can get from DataBinding
like navigation, editing, validation..
手头的问题实际上由三个独立的问题组成:
The issue at hand really consists of three separate problems:
- 您想使用
DataBinding
来多条记录. - 您想要一个免费或表格布局,不是面向行的布局.
- 记录的字段应该进入一个自由布局的显示对象.
- You want to use
DataBinding
to multiple records. - You want a free or tabular layout, not a row-orientated one.
- The fields of a record should go into a freely laid out display object.
对于后者,有许多选项可以从所有者绘制的Panel
子类到定制的UserControl
.我们选择后者,因为它易于编码且易于扩展.
For the latter there are many options going from a owner-drawn Panel
subclass to a custom-made UserControl
. Let's go for the latter as it is simple to code and easier to expand.
第二,我们可以在多个容器控件之间进行选择.我会选择 FlowLayoutPanel
.
For the second we can choose between several container controls. I'll go for a FlowLayoutPanel
.
但是我们如何使用DataBinding
?即使我们绑定了 UC 的成员,我们仍然没有获得多记录数据绑定.
But how can we use DataBinding
? Even if we bind members of the UC we still don't get multi-record data-binding.
解决方法使用我能想到的一个 Winforms
控件,它提供了多记录数据绑定:一个 DatGridView
.但是因为它只会显示一个包含行和列的单元格网格,每个单元格包含一个值,所以我们根本不会让它显示任何内容:
The workaround uses the one Winforms
control I can think of that provides multi-record data-binding: A DatGridView
. But as it will only display a grid of cells with rows and columns, each cell holding one value, we won't let it display anything at all:
DataGridView dataGridView1 = new DataGridView();
DataTable DT = null;
public Form1()
{
InitializeComponent();
dataGridView1.DataSourceChanged += dataGridView1_DataSourceChanged;
}
如您所见,DGV
是严格使用默认值创建的,但并未添加到 Form
,因此它不会显示.
As you can see the DGV
is created strictly with the default values but not added to the Form
, so it doesn't show.
我们只使用它的DataSource
(在加载DataTable
之后,很明显):
We only use its DataSource
(after loading the DataTable
, obvioulsy):
private void button1_Click(object sender, EventArgs e)
{
dataGridView1.DataSource = DT;
}
当 DataSource
更改时,我们清除用于托管显示控件的 FlowLayoutPanel
,并为每个 DataRow
添加一个:
When the DataSource
changes we clear the FlowLayoutPanel
we use to host the display controls and add one for each DataRow
:
private void dataGridView1_DataSourceChanged(object sender, EventArgs e)
{
DataTable dt = (DataTable)dataGridView1.DataSource;
flowLayoutPanel1.Controls.Clear();
foreach (DataRow row in dt.Rows)
{
UCBind ucb = new UCBind(row, imageList1);
flowLayoutPanel1.Controls.Add(ucb);
}
}
FlowLayoutPanel
让生活变得非常简单;只要确保它的大小可以容纳正确数量的显示控件!但是您也可以将它们添加到 TableLayoutPanel
或什至一个简单的 Panel
.对于这些,您需要而且可以确定所有布局细节.
The FlowLayoutPanel
makes life very easy; just make sure its size can hold the right number of display controls! But you could also add them to a TableLayoutPanel
or even a simple Panel
. For these you need to but also can determine all the layout details yourself.
现在是显示控件.
我创建了一个 UserControl UCBind
并在构造函数中传入了一个 DataRow
和一个 ImageList
.代码如下所示:
I have created a UserControl UCBind
and pass in a DataRow
and an ImageList
in the constructor. The code looks like this:
public partial class UCBind : UserControl
{
ImageList imgList { get; set; }
public UCBind()
{
InitializeComponent();
DoubleBuffered = true; // prevent flicker
}
public UCBind(DataRow row, ImageList imglist)
{
InitializeComponent();
DoubleBuffered = true; // prevent flicker
if (row != null)
{
imgList = imglist;
DisplayData(row);
}
}
public void DisplayData(DataRow row)
{
lbl_field1.Text = row.Field<int>(0) + "";
lbl_field2.Text = row.Field<string>(1);
lbl_field3.Text = row.Field<string>(2);
if (imgList != null) BackgroundImage = imgList.Images[row.Field<string>(3)];
}
}
很明显,设计器代码中还有更多内容来设置 UC 及其字段的样式:
Obviously there is a little more going on in the designer code to style the UC and its fields:
- 添加三个
标签
Dock
到Top
.- 设置
AutoSize = false
. - 放大
高度
- 将他们的
ForeColor
设置为White
. - 根据需要更改
字体
. - 将
TextAlignment
设置为Left、Right &没错
. - 将所有
BackColors
设置为Transparent
. - 将
BackgroundImageLayout
设置为Stretch
.
- Add three
Labels
Dock
each to theTop
.- Set
AutoSize = false
. - Enlarge the
Height
- set their
ForeColor
toWhite
. - Change the
Fonts
as needed. - Set
TextAlignment
toLeft, Right & Right
. - Set all
BackColors
toTransparent
. - Set
BackgroundImageLayout
toStretch
.
您还需要将 Size
设置为您想要的值.
You will also want to set the Size
to what you want.
我没有包含设计师生成的代码,因为它往往很长.只需自己创建新的 UserControl
类,添加 Labels
、样式和上面几行构造函数代码..!
I have not included the designer genrated code as it tends to be rather long. Simply create the new UserControl
class yourself, add the Labels
, styling and the few lines of constructor code above..!
为了使它更丰富,您可以尝试添加调整大小的代码,使 FLP
始终填充正确数量的控件.
And to make it rich you could try to add resizing code to make the FLP
always fill with the right number of controls.
显然,如果不扭曲图像,圆角和 3d 边框看起来最好.我使用一个 ImageList
和合适的 ColorDepth
和 ImageSize
值并加载三个 Images
.然后我将一个对它的引用传递给我创建的每个 UC
.ImageList 被添加到表单中,你可以在 VS 设计器中将图像加载到其中.:
Obviously the rounded corners and 3d borders will look best if you don't distort the image. I use an ImageList
with suitable values for ColorDepth
and ImageSize
and load the three Images
. Then I pass a reference to it to each UC
I create.. The ImageList is added to the form and you can load the images into it right in the VS designer..:
这篇关于使用 Windows 窗体数据控件和 DataTable 完成画廊类型的显示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!