c# - 如何从 WPF 中的 ListView 选择中在 DataGrid 上添加数量列

标签 c# wpf xaml data-binding

我有一个 ListView,我选择了它的数据并将其发送到 DataGrid。我在DataGrid的数量列上遇到了麻烦,我想计算 ListView 项目已添加到所述datagrid中的多少次(我当前在选择同一项目时显示成功消息)。我还想计算价格和数量,并将它们显示在 DataGrid 中名为“价格”的一列上。

这是数据网格

 <ListView x:Name="ItemGridView" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" PreviewMouseDoubleClick="ItemGridView_PreviewMouseDoubleClick">    
     <ListView.View>
        <GridView AllowsColumnReorder="False">
           <GridViewColumn>                                                        
               <GridViewColumn.CellTemplate>
                  <DataTemplate>
                     <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal">
                         <Grid Margin="5">
                             <Grid.RowDefinitions>
                                 <RowDefinition Height="Auto" />
                             </Grid.RowDefinitions>
                             <Grid.ColumnDefinitions>
                                 <ColumnDefinition Width="Auto" />
                             </Grid.ColumnDefinitions>

                             <Image Source="{Binding ItemImage}" Width="225" Height="157" Stretch="UniformToFill" StretchDirection="DownOnly" />

                             <StackPanel Margin="0,100,0,0">
                               <Border Margin="-0,-7,0,0"  Height="63" Width="225" Background="{x:Null}" BorderBrush="{x:Null}" BorderThickness="0">
                                   <TextBlock Margin="8" FontWeight="Heavy" Foreground="White" FontSize="16" Text="{Binding ItemName}"/>
                               </Border>
                                <TextBlock Margin="15,-28,0,0" FontSize="15" Text="{Binding SellingPrice}" Foreground="White"/>
                             </StackPanel>
                         </Grid>                                                                    
                     </StackPanel>
                  </DataTemplate>
               </GridViewColumn.CellTemplate>
            </GridViewColumn>
         </GridView>
    </ListView.View>                                               
</ListView>

数据发送到的 DataGrid 如下所示:

<DataGrid x:Name="DGItems" ItemsSource="{Binding}" VerticalAlignment="Top" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="0" MinHeight="350" MaxHeight="350" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto" CanUserSortColumns="True" CanUserAddRows="False" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn MinWidth="3" Header="#" Width="Auto" Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Converter={global:RowToIndexConverter}}" />
        <DataGridTextColumn Header="Items" Binding="{Binding ItemName}" />
        <DataGridTextColumn Header="Cost" Binding="{Binding SellingPrice}" />
        <DataGridTextColumn Header="Qty"  />           
    </DataGrid.Columns>
</DataGrid>

在 ListView 双击事件之后发送数据的代码如下:

 private void ItemGridView_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
 {
      var selectedItem = ItemGridView.SelectedItem;

      if (!DGItems.Items.Contains(selectedItem))
      {
          DGItems.Items.Add(selectedItem);
      }
      else
      {
          utilityMethods.InformationMessage("Attempted to add item successfully");                
      }

 }

我已经包含截图来预览应用程序的外观,只是为了将问题放在上下文中。

Sale Screen Screenshot

最佳答案

这是一个工作示例。我对您的 xaml 和绑定(bind)做了一些修改,以展示它是如何完成的。每当您双击 ListView 中的项目时,它都会更新 DataGrid 中的 Quantity 和 Total 列。
enter image description here
MyItem.cs:这是一个简单的模型来复制您的食品

namespace UpdateQuantityColumnTest
{
    public class MyItem
    {
        public string ItemName { get; set; }
        public double SellingPrice { get; set; }
    }
}
ListViewItemViewModel.cs:这是 ListView 的 MyItem 的 View 模型表示
namespace UpdateQuantityColumnTest
{
    public class ListViewItemViewModel : ViewModelBase
    {
        public ListViewItemViewModel(MyItem model)
        {
            this.Model = model;
        }

        public MyItem Model { get; private set; }

        public string ItemName { get => this.Model.ItemName; set { this.Model.ItemName = value; OnPropertyChanged(); } }
        public string SellingPrice { get => this.Model.SellingPrice.ToString("c"); }
    }
}
DGItemViewModel:这是 DataGrid 的 MyItem 的 View 模型表示稍有不同,但包括 Quantity 和 TotalPrice
namespace UpdateQuantityColumnTest
{
    public class DGItemViewModel : ViewModelBase
    {
        private int quantity;

        public DGItemViewModel(MyItem model)
        {
            this.Model = model;
            this.quantity = 1; // always start at 1
        }

        public MyItem Model { get; private set; }
        public string ItemName { get => this.Model.ItemName; set { this.Model.ItemName = value; OnPropertyChanged(); } }
        public string SellingPrice { get => this.Model.SellingPrice.ToString("c"); }
        public int Quantity { get => this.quantity; set { this.quantity = value; OnPropertyChanged(); OnPropertyChanged(nameof(TotalPrice)); } }
        public string TotalPrice { get => (this.Model.SellingPrice * this.Quantity).ToString("c"); }
    }
}
ViewModelBase.cs:这是一个基类,它简单地处理 INotifyPropertyChanged 以在 View 模型中的属性值之一发生更改时更新 UI
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace UpdateQuantityColumnTest
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
MainWindow.xaml:我做了一些小改动,主要是对您的绑定(bind),以便我的示例可以工作
<Window x:Class="UpdateQuantityColumnTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ListView x:Name="ItemGridView" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" PreviewMouseDoubleClick="ItemGridView_PreviewMouseDoubleClick">
            <ListView.View>
                <GridView AllowsColumnReorder="False">
                    <GridViewColumn>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal">
                                    <Grid Margin="5">
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto" />
                                        </Grid.RowDefinitions>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto" />
                                        </Grid.ColumnDefinitions>

                                        <Image Source="{Binding ItemImage}" Width="225" Height="157" Stretch="UniformToFill" StretchDirection="DownOnly" />
                                        <StackPanel Margin="0,100,0,0">
                                            <Border Margin="-0,-7,0,0"  Height="63" Width="225" Background="{x:Null}" BorderBrush="{x:Null}" BorderThickness="0">
                                                <TextBlock Margin="8" FontWeight="Heavy" Foreground="White" FontSize="16" Text="{Binding ItemName}"/>
                                            </Border>
                                            <TextBlock Margin="15,-28,0,0" FontSize="15" Text="{Binding SellingPrice}" Foreground="White"/>
                                        </StackPanel>
                                    </Grid>
                                </StackPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
        <DataGrid x:Name="DGItems" ItemsSource="{Binding CheckoutItems}" VerticalAlignment="Top" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="1" MinHeight="350" MaxHeight="350" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto" CanUserSortColumns="True" CanUserAddRows="False" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Items" Binding="{Binding ItemName}" />
                <DataGridTextColumn Header="Cost" Binding="{Binding SellingPrice}" />
                <DataGridTextColumn Header="Qty"  Binding="{Binding Quantity}"/>
                <DataGridTextColumn Header="Total"  Binding="{Binding TotalPrice}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
MainWindow.xaml.cs:完成所有工作的代码隐藏
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace UpdateQuantityColumnTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<ListViewItemViewModel> items;
        private ObservableCollection<DGItemViewModel> checkoutItems;

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += OnLoaded;
            this.DataContext = this;
        }

        public ObservableCollection<ListViewItemViewModel> Items
        {
            get
            {
                if (this.items == null)
                    this.items = new ObservableCollection<ListViewItemViewModel>();
                return this.items;
            }
        }

        public ObservableCollection<DGItemViewModel> CheckoutItems
        {
            get
            {
                if (this.checkoutItems == null)
                    this.checkoutItems = new ObservableCollection<DGItemViewModel>();
                return this.checkoutItems;
            }
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            // Populate with dummy data
            this.Items.Add(new ListViewItemViewModel(new MyItem() { ItemName = "Beef Steak", SellingPrice = 1000 }));
            this.Items.Add(new ListViewItemViewModel(new MyItem() { ItemName = "Bacon Brie", SellingPrice = 1200 }));
            this.Items.Add(new ListViewItemViewModel(new MyItem() { ItemName = "Bread and Sausage", SellingPrice = 700 }));
        }

        private void ItemGridView_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var selectedItem = ItemGridView.SelectedItem as ListViewItemViewModel;
            var checkoutItem = this.CheckoutItems.SingleOrDefault(o => o.ItemName == selectedItem.ItemName);

            if (checkoutItem == null)
            {
                this.CheckoutItems.Add(new DGItemViewModel(selectedItem.Model));
            }
            else
            {
                //utilityMethods.InformationMessage("Attempted to add item successfully");
                checkoutItem.Quantity++;
            }

        }
    }
}

关于c# - 如何从 WPF 中的 ListView 选择中在 DataGrid 上添加数量列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61265978/

相关文章:

c# - Web API 2 中依赖注入(inject)的服务授权

c# - 对象的 WPF 绑定(bind)列表到自定义控件

c# - "Can' t 在指定文件夹中找到 .NET 程序集 {AssemblyName}”

c# - 使用路径和值更新 JSON 对象

c# - 从多线程数据源平滑更新图表

wpf - 如何在 xaml 的 DataGrid 列标题中右对齐文本?

c# - 在 silverlight 中刷新 DataGrid

c# - WP增加全景重叠

wpf - 如何将文本框数据绑定(bind)到 CodeBehind 中的属性

c# - WPF Combobox Itemssource 是 Visibility Enum