好。经过几个小时的思考后,我决定再次提出我的问题,因为即使我在前一个问题的答案中得到了一些指导,但我还是无法工作。 Here's my original question
现在我正在创建一个销售点系统,我想在我的数据库中动态显示产品,作为TabControl上的按钮 - TabPages根据他们的ProductType。但问题是,我可以将这些产品作为按钮提供给TabPags,但我不能根据他们的ProductType将它们排序到每个TabPage,因为相同的产品列表显示在每个TabPage上,如下所示。
这是我的数据库。
private void CreateTabPages() // Create Tab Pages for each ProductType
{
con.Open();
SqlDataAdapter sda = new SqlDataAdapter("SELECT DISTINCT ProductType, Description FROM TblProductType", con);
DataTable dt = new DataTable();
sda.Fill(dt);
foreach (DataRow dr in dt.Rows)
{
tabControl1.TabPages.Add(dr["ProductType"].ToString(),dr["Description"].ToString());
}
con.Close();
}
private void AddProductsToTabbedPanel() // Add Products to Tab Pages
{
foreach (TabPage tp in tabControl1.TabPages)
{
con.Open();
SqlDataAdapter sda = new SqlDataAdapter("SELECT DISTINCT Description FROM TblProduct", con);
DataTable dt = new DataTable();
sda.Fill(dt);
FlowLayoutPanel flp = new FlowLayoutPanel();
flp.Dock = DockStyle.Fill;
foreach (DataRow dr in dt.Rows)
{
Button b = new Button();
b.Size = new Size(100, 100);
b.Text = dr["Description"].ToString();
flp.Controls.Add(b);
}
tp.Controls.Add(flp);
con.Close();
}
}
我非常感谢你能给我的任何反馈。
答案 0 :(得分:1)
免责声明:是的,我知道OP的图片显示的是WinForms,但在the other question中,OP表示他们正在关注YouTube
的教程。我以为我会提供另一种方法,他可以用WPF表示相同的数据。
您可以使用Model
来显示每个DataTypes
,而不是处理Raw Data
;看看Object-Relational Mapping,比如Entity-Framework,NHibernate等。
创建Product
模型以保存Product
表中的数据。
public class Product {
public int ProductID {get;set;}
public int ProductType { get; set; }
public string Description { get; set; }
public double Price { get; set; }
public byte[] Image { get; set; }
}
创建Product Type
模型以保存Product Type
表中的数据。
public class ProductType {
public int ProductTypeID { get; set; }
public string Description { get; set; }
}
创建Window
/ UserControl
来保留TabControl
。
<Window.Resources>
<local:ProductConverter x:Key="ProductConverter" />
<local:ProductTypeConverter x:Key="ProductTypeConverter" />
</Window.Resources>
<TabControl ItemsSource="{Binding MyProducts,
Converter={StaticResource ProductConverter}}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource ProductTypeConverter}">
<Binding Path="ProductType"/>
<Binding Path="DataContext.MyProductTypes"
RelativeSource="{RelativeSource AncestorType={x:Type Window}}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Width="150" Content="{Binding Description}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
使用ItemTemplate
和ContentTemplate
可确保您的所有Product
对象具有相同的格式和样式。
这是一个转换器,可根据Products
值将整个Products
列表转换为Product Type
组。
public class ProductConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
if(value as List<Product> != null) {
return (value as List<Product>).GroupBy(a => new { a.ProductType });
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
return null;
}
}
这是将Product.ProductType
值转换为ProductType.Description
public class ProductTypeConverter : IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
if(values[0] != null && values[0] != DependencyProperty.UnsetValue &&
values[1] != null && values[1] != DependencyProperty.UnsetValue) {
string f= (values[1] as List<ProductType>)
.Where(a => a.ProductTypeID.Equals(values[0]))
.First().Description;
return f;
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
return null;
}
}
创建Properties以便在显示TabControl.Items
。
public List<Product> MyProducts { get; set; }
public List<ProductType> MyProductTypes { get; set; }
之后,您所要做的就是以模型格式表示Raw Data
。 (我的SQL有点不确定)
SqlCommand sqlCmdProducts = new SqlCommand("SELECT * FROM TblProduct", myConnection);
SqlDataReader productReader = sqlCmdProducts.ExecuteReader();
while (productReader.Read()) {
MyProductTypes.Add(new ProductType() {
ProductTypeID = Int32.Parse(productReader["ProductType"].ToString()),
Description = Int32.Parse(productReader["Description"].ToString()),
};
}
SqlCommand sqlCmdProductType = new SqlCommand("SELECT * FROM TblProductType", myConnection);
SqlDataReader productTypeReader = sqlCmdProductType.ExecuteReader();
while (productTypeReader.Read()) {
MyProducts.Add(new Product() {
ProductID = Int32.Parse(productTypeReader["ProductID"].ToString()),
ProductType = Int32.Parse(productTypeReader["ProductType"].ToString()),
Description = productTypeReader["Description"].ToString()),
Price = double.Parse(productTypeReader["Price"].ToString()),
};
}