【问题标题】:Bind Collection to ListView, suppress duplicates of object but manipulate ListViewItem将 Collection 绑定到 ListView,禁止重复对象但操作 ListViewItem
【发布时间】:2018-01-03 03:14:10
【问题描述】:

我在 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,而是通过在现有商品上添加相同的价格来操作现有的ListViewItem

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

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

在此先感谢并原谅我糟糕的英语语法:)

【问题讨论】:

  • 你需要一个额外的属性,比如“count”,它最初在 new 上设置为 1 - 然后每次需要添加相同的项目时,你看看你是否已经拥有它并增加 count 属性,否则你添加一个新项目 - 所以“添加”代码需要完成这项工作
  • 我不太明白你所说的“如果一个产品被扫描两次,而不是添加一个新的 ListViewItem,而是应该通过在现有的 Item 上添加相同的 Price 来操作现有的 ListViewItem 。”你能详细说明一下吗?
  • 就我个人而言,我会创建一个ProductGroup 作为ListView 的基础项目模型。就像@user230910 已经建议的那样,对于这个新课程,您将需要一个Count,您可能还需要一个TotalPrice,基本上是Price * Count。这就是为什么大多数时候我们需要一个 VM 来扩展我们的模型类。在您的情况下,ProductGroup 将充当有助于满足 UI 需求的 VM。
  • @JustinXL 正是我的意思——说得好:)
  • 好的,现在我明白了,解释得很好。如果我找到可能的解决方案,我会尽力并在这里回复。

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


【解决方案1】:

所以,在@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;
    }
}

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

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

【讨论】:

    猜你喜欢
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    相关资源
    最近更新 更多