c# - 将 Collection 绑定(bind)到 ListView,抑制对象的重复但操作 ListViewItem

标签 c# wpf xaml uwp .net-core

我的问题是,在 Raspberry Pi 3 Bodel B 上开发购物系统,如下所示:

首先是一些背景:

  1. 带条码扫描器的树莓派用作自助商店

    • 员工扫描饮料,屏幕上的价格会与饮料的价格相加
    • 现在应该提供一个扩展:应该显示所有当前扫描的产品的列表。
  2. 到目前为止,我只实现了,每个扫描的产品在 ListView 中显示为一个 ListViewItem

这是我的模型

    public partial class Product : object, System.ComponentModel.INotifyPropertyChanged {
    private string DescriptionField;
    private System.DateTime ExpirationDateField;
    private int IDField;
    private string NameField;
    private decimal PriceField;

    [System.Runtime.Serialization.DataMemberAttribute()]
    public string Description {
        get {
            return this.DescriptionField;
        }
        set {
            if ((object.ReferenceEquals(this.DescriptionField, value) != true)) {
                this.DescriptionField = value;
                this.RaisePropertyChanged("Description");
            }
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute()]
    public System.DateTime ExpirationDate {
        get {
            return this.ExpirationDateField;
        }
        set {
            if ((this.ExpirationDateField.Equals(value) != true)) {
                this.ExpirationDateField = value;
                this.RaisePropertyChanged("ExpirationDate");
            }
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute()]
    public int ID {
        get {
            return this.IDField;
        }
        set {
            if ((this.IDField.Equals(value) != true)) {
                this.IDField = value;
                this.RaisePropertyChanged("ID");
            }
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute()]
    public string Name {
        get {
            return this.NameField;
        }
        set {
            if ((object.ReferenceEquals(this.NameField, value) != true)) {
                this.NameField = value;
                this.RaisePropertyChanged("Name");
            }
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute()]
    public decimal Price {
        get {
            return this.PriceField;
        }
        set {
            if ((this.PriceField.Equals(value) != true)) {
                this.PriceField = value;
                this.RaisePropertyChanged("Price");
            }
        }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName) {
        System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if ((propertyChanged != null)) {
            propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}

此模型描述了可以在我们商店购买的产品。

我的 XAML 代码段

<ListView Name="ProductSumUp" 
          AllowDrop="False"  
          SelectionMode="None" 
          CanDrag="False" 
          CanReorderItems="False" 
          CanDragItems="False" 
          Grid.Column="2" 
          HorizontalAlignment="Left" 
          Height="290" 
          Margin="10,10,0,0" 
          Grid.Row="1" 
          VerticalAlignment="Top" 
          Width="180" 
          RenderTransformOrigin="1.682,0.59" 
          Foreground="White" 
          FontFamily="Assets/Fonts/Baskerville.ttf#Baskerville">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <TextBlock FontFamily="Assets/Fonts/Baskerville.ttf#Baskerville" 
                               Foreground="White">
                        <Run Text="{Binding Name}"/>
                        <Run x:Name="{Binding Price}"/>
                        </TextBlock>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

现在我的问题是:

如果产品被扫描两次,是否可以不添加新的 ListViewItem,而是应该通过在现有项目。

我尝试了很多可能性,也问过我工作中的一些开发人员,但没有人能弄清楚。

如果您需要更多信息,请询问。

提前致谢,请原谅我糟糕的英语语法:)

最佳答案

因此,在@JustinXL 和@user230910 的大力支持下,我自己制定了一个解决方案。

我只是在这里发布我的代码,所以你可以看到我找到了一个解决方案。

XAML

<ListView.ItemTemplate>
    <DataTemplate>
        <Grid>
            <TextBlock 
             FontFamily="Assets/Fonts/Baskerville.ttf#Baskerville" 
             Foreground="White">
                <Run Text="{Binding Path=groupedProduct.Name}"/>
                <Run Text="{Binding PriceSum,
                            Converter={StaticResource PriceConverter}, 
                            Mode=TwoWay,
                            UpdateSourceTrigger=PropertyChanged}"/>
                <LineBreak/>
                <Run Text="{Binding Path=Count,
                            Converter={StaticResource StringFormatter},
                            ConverterParameter='Anzahl: {0}',
                            Mode=TwoWay,
                            UpdateSourceTrigger=PropertyChanged}"/>
        </Grid>
    </DataTemplate>
</ListView.ItemTemplate>

C# - 模型代码

public class ProductGroup : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void onPropertyChanged(object sender, string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
            }
        }

        private decimal _priceSum;
        private int _count;
        public Product groupedProduct { get; set; }
        public int Count
        {
            get
            {
                return _count;
            }
            set
            {
                _count = value;
                onPropertyChanged(this, "Count");
            }
        }
        public decimal Price { get; set; }
        public decimal PriceSum
        {
            get { return _priceSum; }
            set
            {
                _priceSum = value;
                onPropertyChanged(this, "PriceSum");
            }
        }
    }

C# - 集合填充

ProductSumUp.ItemsSource = _showProducts;

bool prodExists = false;

foreach (ProductGroup prodz in _showProducts)
{
     if (prodz.groupedProduct.ID == prod.ID)
        {
          prodExists = true;
        }
}

if (!prodExists)
{
    ProductGroup prodGroup = new ProductGroup();
    prodGroup.groupedProduct = prod;
    prodGroup.Price = prod.Price;
    prodGroup.Count = 1;
    prodGroup.PriceSum += prod.Price;
    _showProducts.Add(prodGroup);
}
 else
{
    ProductGroup pgroup = _showProducts.First(x => x.groupedProduct.ID == prod.ID);

    if (pgroup != null)
    {
        pgroup.Count++;
        pgroup.PriceSum += pgroup.Price;
    }
}

result

请不要评判我的编程风格,我解决问题的方式又快又脏。

我希望有人可以使用我的解决方案来解决他/她的问题,感谢您的帮助,它节省了我很多时间。

关于c# - 将 Collection 绑定(bind)到 ListView,抑制对象的重复但操作 ListViewItem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45349969/

相关文章:

c# - 如何使用 Resources.resx 链接图像

xaml - 无法使用 Telerik.UI.Xaml.Controls.Grid 命名空间添加

c# - 列表框项目WPF,不同项目的不同背景颜色

WPF:ScrollViewer 和 Grid - 禁用 TexBox 调整大小

c# - 具有动态命名参数的扩展方法

c# - 使用 C# 在 Excel 中更改单元格颜色

c# - 为什么 User.Identity 不包含 ClaimsTypes 的完整列表?

c# - DateTime.Today ,一天的开始还是结束?

c# - 如何从本地路径清除图像控件

c# - 如何将命令绑定(bind)到按钮