2

如果我有这样的Observable收藏:

public ObservableCollection<SpecialPriceRow> SpecialPriceRows = new ObservableCollection<SpecialPriceRow>();

SpecialPriceRow班级 :

public class SpecialPriceRow : INotifyPropertyChanged
{
    public enum ChangeStatus
    {
        Original,
        Added,
        ToDelete,
        Edited
    }

    public ChangeStatus Status { get; set; }
    public string PartNo { get; set; }

    private decimal _price;
    public decimal Price
    {
        get
        {
            return _price;
        }
        set
        {
            if (value != _price)
            {
                _price = value;
                Status = ChangeStatus.Edited;
                OnPropertyChanged("Status");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

我是否可以将 XAML 中的标签绑定到说...添加的对象的计数?所以我可以得到这样的东西:

在此处输入图像描述

其中绿色是集合中“已添加”对象的计数。我将如何去做这样的事情?

4

2 回答 2

0

I'm not aware of any builtin functionality to do this. I would create a custom property in your data context class that does the counting and bind to this.

Something like this:

public int AddedCount
{
    get
    {
        return SpecialPriceRows.Where(r => r.Status == ChangeStatus.Added).Count();
    }
}

Then whenever an item is changed or added you need to explicitly raise the property changed for this:

public void AddItem()
{
    ...
    OnPropertyChanged("AddedCount");
}

Then you only need to bind in your XAML code like:

<TextBlock Text="{Binding AddedCount}" />

You may need to subscribe to the change events in your collection to know when an item changes.

Alternative:

You can also create a ListCollectionView with a specific filter and bind to its Count property:

    AddedItems = new ListCollectionView(TestItems);
    AddedItems.Filter = r => ((SpecialPriceRow)r).Status == ChangeStatus.Added;

In your XAML you would then bind to the Count property of this:

<TextBlock Text="{Binding AddedItems.Count}" />

This has the advantage that it will automatically keep track of added and removed items in the collection and update itself. You have to refresh it manually though when the property of an item changes which affects the filter.

于 2013-02-03T01:36:09.470 回答
0

我已经编写了一个 ViewModel,它将执行您正在寻找的所需功能。

    class VM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public ObservableCollection<SpecialPriceRow> _SpecialPriceRows = new ObservableCollection<SpecialPriceRow>();
        private int _Original = 0;
        private int _Added = 0;
        private int _ToDelete = 0;
        private int _Edited = 0;

        public VM()
        {
            PropertyChanged = new PropertyChangedEventHandler(VM_PropertyChanged);

            //The following lines in the constructor just initialize the SpecialPriceRows.
            //The important thing to take away from this is setting the PropertyChangedEventHandler to point to the UpdateStatuses() function.
            for (int i = 0; i < 12; i++)
            {
                SpecialPriceRow s = new SpecialPriceRow();
                s.PropertyChanged += new PropertyChangedEventHandler(SpecialPriceRow_PropertyChanged);
                SpecialPriceRows.Add(s);
            }
            for (int j = 0; j < 12; j+=2)
                SpecialPriceRows[j].Price = 20;
        }

        private void VM_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
        }

        private void SpecialPriceRow_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Status")
                UpdateStatuses();
        }

        public ObservableCollection<SpecialPriceRow> SpecialPriceRows
        {
            get
            {
                return _SpecialPriceRows;
            }
        }

        private void UpdateStatuses()
        {
            int original = 0, added = 0, todelete = 0, edited = 0;
            foreach (SpecialPriceRow SPR in SpecialPriceRows)
            {
                switch (SPR.Status)
                {
                    case SpecialPriceRow.ChangeStatus.Original:
                        original++;
                        break;
                    case SpecialPriceRow.ChangeStatus.Added:
                        added++;
                        break;
                    case SpecialPriceRow.ChangeStatus.ToDelete:
                        todelete++;
                        break;
                    case SpecialPriceRow.ChangeStatus.Edited:
                        edited++;
                        break;
                    default:
                        break;
                }
            }
            Original = original;
            Added = added;
            ToDelete = todelete;
            Edited = edited;
        }

        public int Original
        {
            get
            {
                return _Original;
            }
            set
            {
                _Original = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Original"));
            }
        }

        public int Added
        {
            get
            {
                return _Added;
            }
            set
            {
                _Added = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Added"));
            }
        }

        public int ToDelete
        {
            get
            {
                return _ToDelete;
            }
            set
            {
                _ToDelete = value;
                PropertyChanged(this, new PropertyChangedEventArgs("ToDelete"));
            }
        }

        public int Edited
        {
            get
            {
                return _Edited;
            }
            set
            {
                _Edited = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Edited"));
            }
        }
    }

注意构造函数中的注释。您需要将每个 SpecialPriceRow 的 PropertyChanged 事件指向 UpdateStatuses 函数,以使其正常工作。现在您需要做的就是将您的标签绑定到 ViewModel 中的适当属性。如果您的 SpecialPriceRows 列表变得非常大,您可能需要考虑稍微不同地计算状态计数。目前,每次更新一个实例时,它都会遍历整个列表。为了更好地执行此操作,您可能希望在 SpecialPriceRow 类中保留旧的状态值,并且每次发生更新时,增加新的状态计数并减少旧的状态计数。

于 2013-02-03T01:58:13.477 回答