簡體   English   中英

如何獲取從可觀察集合中編輯的實例? 未添加或刪除

[英]How to get instances that get edited from observable collection? not added or removed

我的 class 中有一個可觀察集合,我希望在可觀察集合發生變化時得到通知。

我在 stackoverflow 上搜索並找到了這段代碼

 private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                foreach (var item in e.OldItems)
                {
                    //Removed items
                    
                }
            }
            else if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (var item in e.NewItems)
                {
                    //Added items
                }
            }
            else if(e.Action == NotifyCollectionChangedAction.Replace){
                foreach (var item in e.NewItems)
                {

                }
            }
        }

一切都很好。 當創建和刪除某些內容時,我會收到通知。 但是在編輯實例時我沒有收到通知。 我做錯什么了?

編輯:我將可觀察集合更改為綁定列表,但是當我編輯某些內容時沒有任何反應。

 <ListView Grid.Row="1" ItemsSource="{Binding Contacts}">
        <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                                <TextBox Text={Binding Name}></TextBox>
                                <TextBox Text={Binding Email}><TextBox>
                            </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView.Columns>
        </GridView>
        </ListView.View>
    </ListView>

我的視圖模型:

    private BindingList<ContactViewModel> _contacts;
    public IEnumerable<ContactViewModel> Contacts=>_contacts;
    public ContactListing()
    {
        _contacts.ListChanged +=_contacts_ListChanged;          

    }

    private void _contacts_ListChanged(object sender, ListChangedEventArgs e)
    {
        //Get Notified When somthing is edited
    }

在 xaml 中,我有一些文本框,當它們的文本發生變化時,綁定列表或可觀察集合也會發生變化(我設置了一個斷點,每次編輯內容時列表都會發生變化)但 ListChanged 事件不會調用。

集合元素必須實現INotifyPropertyChanged 並且集合需要替換為BindingList< T> 然后在ListChanged 事件中,您將收到有關集合元素屬性更改的通知。 您還可以訪問AddingNew 事件,該事件發生在將元素添加到集合之前。

它也不適用於編輯。 它僅適用於創建和刪除。

這是一個示例,顯示它在添加元素和更改元素的任何屬性時有效。

using Simplified;

namespace Core2023.SO.Eboy
{
    public class ItemInpc : BaseInpc
    {
        private int _value;
        private string title = string.Empty;

        public int Id { get; }
        public string Title { get => title; set => Set(ref title, value ?? string.Empty); }
        public int Value { get => _value; set => Set(ref _value, value); }

        public override string? ToString()
            => $"{Id}: {Title}-{Value}";

        public ItemInpc(int id)
        {
            Id = id;
        }
        public ItemInpc() : this(-1) { }
    }
}
using Simplified;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace Core2023.SO.Eboy
{
    public class ItemsViewModel : BaseInpc
    {
        private string _listChangedArgs = string.Empty;

        public BindingList<ItemInpc> Items { get; }

        public ItemsViewModel()
        {
            Items = new BindingList<ItemInpc>(
                "And the collection needs to be replaced"
                .Split()
                .Select((title, id) => new ItemInpc(id) { Title = title, Value = id * 23 })
                .ToList());
            Items.AddingNew += OnAddingNew;
            Items.ListChanged += OnListChanged;
        }

        public string ListChangedArgs { get => _listChangedArgs; set => Set(ref _listChangedArgs, value); }

        private void OnAddingNew(object? sender, AddingNewEventArgs e)
        {
            int id = Items.Max(it => it.Id) + 1;
            ItemInpc item = new ItemInpc(id);
            e.NewObject = item;
        }

        int i = 0;
        private void OnListChanged(object? sender, ListChangedEventArgs e)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(i);
            i++;
            builder.AppendLine(new string('-', 40));
            builder.AppendLine(e.ListChangedType.ToString());
            builder.AppendLine(e.PropertyDescriptor?.Name);
            builder.AppendLine(e.NewIndex.ToString());
            if (e.NewIndex < 0)
                builder.AppendLine($"{e.NewIndex}");
            else
                builder.AppendLine($"{e.NewIndex} {Items[e.NewIndex]}");
            if (e.OldIndex < 0)
                builder.AppendLine($"{e.OldIndex}");
            else
                builder.AppendLine($"{e.OldIndex} {Items[e.OldIndex]}");

            builder.AppendLine(ListChangedArgs);

            ListChangedArgs = builder.ToString();
        }
    }
}
<Window x:Class="Core2023.SO.Eboy.ItemChangedWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Core2023.SO.Eboy"
        mc:Ignorable="d"
        Title="ItemChangedWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:ItemsViewModel/>
    </Window.DataContext>
    <UniformGrid Columns="2">
        <DataGrid ItemsSource="{Binding Items}"/>
        <TextBlock Text="{Binding ListChangedArgs}"/>
    </UniformGrid>
</Window>

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM