将集合绑定到ListView,抑制对象的重复但操纵ListViewItem

时间:2017-07-27 11:49:45

标签: c# wpf xaml uwp .net-core

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

首先是一些背景:

  1. 带条码扫描器的Raspberry Pi用作自助商店

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

  3. 这是我的模特

        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,则可以通过在现有项目上添加相同的价格来操纵现有的ListViewItem

    我尝试了很多可能性,并且在我的工作中也询问了一些开发人员,但没有人能想出来。

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

    提前致谢,请原谅我可怕的英语语法:)

1 个答案:

答案 0 :(得分:2)

所以,我自己在@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# - Modelcode

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# - CollectionFill

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

请不要判断我的编程风格,我快速解决了问题。

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