【问题标题】:Is there a way to loop through elements in c# wpf and connect them to a MySQL database? [closed]有没有办法遍历 c# wpf 中的元素并将它们连接到 MySQL 数据库? [关闭]
【发布时间】:2019-05-12 05:11:42
【问题描述】:

我正在用 c# 制作一种网上商店。所以我有这个 UI(见图),我想通过循环(更少的代码)将数据绑定到 UI 元素。我可以用很多代码来完成这本手册,但这不是我想要的。我正在考虑元素循环,但我找不到任何相关信息。 有谁知道如何做到这一点?

【问题讨论】:

  • 由于此问题中没有代码或 xaml,我猜您需要建议。我的建议是你不要害怕写代码,使用 MVVM 模式和最常见的绑定方式。这将在此过程中为您提供最丰富的体验和灵活的应用程序,未来的更改会容易得多
  • “我想用循环将数据绑定到 UI 元素”你甚至不需要循环。只需使用ItemsControl
  • 基本上,你的图片看起来像ListBox + WrapPanel + ItemTemplate。但它所说的问题太宽泛了。

标签: c# mysql database wpf loops


【解决方案1】:

根据您的要求,我建议您遵循 MVVM,正如 cmets 中所建议的那样。以下是实现您的目标的步骤。

  1. 定义您的模型,其中包含所有必需的属性,例如图片、ID、标题、描述等。
  2. 定义包含模型的 ObservalbeCollection 或 List(根据您的要求)的 ViewModel。
  3. 使用您喜欢的任何 ORM 从 DB 中填写您的集合。
  4. 您需要美化 UI 以显示项目列表。我建议您使用列表视图并定义(ItemTemplate、ItemContainerStyle 和 ItemPanel)。
  5. 将列表视图与 VM 的属性(模型的集合)绑定。 就是这样

注意:在每个项目中都有按钮。当您将项目源设置为列表视图时,默认情况下它将在相关模型中查找命令。如果要为所有item按钮定义通用Command,则需要在VM中创建Command,并通过RelativeSource和查找Ancestor将该命令绑定到listview itemtemplate Button,以便在祖先datacontext中搜索VM的Command。

【讨论】:

    【解决方案2】:

    定义产品型号:

    public sealed class Product
    {
        public string Name { get; set; }
    
        public string Description { get; set; }
    
        public byte[] Image { get; set; }
    }
    

    定义服务以从数据库加载产品:

    public sealed class ProductsService
    {
        public async Task<IEnumerable<Product>> LoadProductsAsync()
        {
            // TODO: to load products from database use your favorite ORM
            // or raw ADO .NET; anyway, you want this to be async
            // since this is I/O bound operation
        }
    }
    

    定义产品视图模型。它只是包装模型并提供“添加到购物车”命令:

    public sealed class ProductVm : ViewModelBase
    {
        private readonly Product model;
        private readonly Lazy<ImageSource> image;
    
        public ProductVm(Product model)
        {
            this.model = model;
    
            // we need to load image just once, hence here comes Lazy<T>
            image = new Lazy<ImageSource>(LoadImage);
    
            // TODO: add command initialization here;
            // usually you want DelegateCommand/RelayCommand/etc
            // AddToCartCommand = new DelegateCommand(AddToCart);
        }
    
        public string Name => model.Name;
    
        public string Description => model.Description;
    
        public ImageSource Image => image.Value;
    
        public ICommand AddToCartCommand { get; }
    
        private ImageSource LoadImage()
        {
            if (model.Image == null)
            {
                return null;
            }
    
            var image = new BitmapImage();
    
            using (var mem = new MemoryStream(model.Image))
            {
                image.BeginInit();
                image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.UriSource = null;
                image.StreamSource = mem;
                image.EndInit();
            }
    
            image.Freeze();
    
            return image;
        }
    }
    

    定义主窗口视图模型:

    public sealed class MainWindowVm
    {
        private readonly ProductsService productsService;
        private ObservableCollection<ProductVm> products;
    
        public MainWindowVm()
        {
            // in production apps, services must be injected using DI-containers
            // like Autofac, MEF, NInject, etc
            productsService = new ProductsService();
        }
    
        public IEnumerable<ProductVm> Products
        {
            get
            {
                if (products == null)
                {
                    // when UI wants to display products,
                    // we create empty collection and initiate async operation;
                    // later, when async operation will be finished,
                    // we will populate collection using values from database
                    products = new ObservableCollection<ProductVm>();
    
                    var _ = LoadProductsAsync();
                }
    
                return products;
            }
        }
    
        private async Task LoadProductsAsync()
        {
            // service returns collection of product models,
            // but we need collection of product view models
            var productModels = await productsService.LoadProductsAsync();
    
            foreach (var model in productModels)
            {
                products.Add(new ProductVm(model));
            }
        }
    }
    

    定义一个视图。你需要ItemsControlItemTemplateWrapPanel

    <Window x:Class="WpfApp3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp3"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
    
        <Window.DataContext>
            <local:MainWindowVm />
        </Window.DataContext>
    
        <ItemsControl ItemsSource="{Binding Products}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
    
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type local:ProductVm}">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
    
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
    
                        <Image Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Width="48" Height="48" Source="{Binding Image}"/>
    
                        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Name}"/>
                        <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Description}"/>
                        <Button Grid.Row="2" Grid.Column="1" Content="Add to cart" HorizontalAlignment="Right" Command="{Binding AddToCartCommand}"/>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Window>
    

    结果:

    示例项目是here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-14
      • 1970-01-01
      • 2021-12-13
      • 2021-06-28
      • 2013-07-26
      • 1970-01-01
      • 2021-05-19
      相关资源
      最近更新 更多