سؤال

لدي هذا DependencyProperty الذي يحمل كيانًا له خاصية عبارة عن مجموعة (ShoutBox.Entities):

public static readonly DependencyProperty ShoutBoxProperty = DependencyProperty.Register("ShoutBox",typeof (ShoutBox),typeof (ShoutBoxViewerControl));

public ShoutBox ShoutBox
{
    get { return (ShoutBox) GetValue(ShoutBoxProperty); }
    set { SetValue(ShoutBoxProperty, value); }
}

يتم ربطه xaml مثل هذا:

<ItemsControl ItemsSource="{Binding ShoutBox.Entries}">
.
.
</ItemsControl>

عندما أقوم بربطها في المرة الأولى، فإنها تعمل كما هو متوقع ولكن هناك أوقات أحتاج فيها إلى إضافة عناصر إلى المجموعة (بطريقة موجودة في نفس عنصر التحكم)، مثل هذا:

public void AddNewEntry(ShoutBoxEntry newEntry)
{
    Dispatcher.Invoke(new Action(() =>{
        ShoutBox.Entries.Add(newEntry); //Adding directly the the Dependency property
    }));
}

المشكلة هي أنه عندما أقوم بإضافة عنصر جديد بالطريقة المذكورة أعلاه، لا يتم عرض العنصر في ملف ItemsControl.


سؤالي هو، لماذا لا يتم عرض العنصر الجديد الذي أقوم بإضافته في ملف ItemsControl ?


[يحرر]

Entries (ShoutBox.Entries) من النوع List<ShoutBoxEntry>

هل كانت مفيدة؟

المحلول

ما هو نوع الإدخالات؟يجب أن يكون ObservableCollection أو تطبيق ICollectionChanged.وإلا فلن يعرف الرابط أنه تمت إضافة عنصر جديد.

نصائح أخرى

إن تغيير نوع الإدخالات يجب أن يحل المشكلة بالفعل ...إذا كنت تريد تجنب الاستدعاء الصريح لـ Dispatcher.Invoc، فقد كتبت مجموعة ترفع الحدثين CollectionChanged وPropertyChanged على مؤشر الترابط الذي أنشأ المجموعة:

public class AsyncObservableCollection<T> : ObservableCollection<T>
{
    private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;

    public AsyncObservableCollection()
    {
    }

    public AsyncObservableCollection(IEnumerable<T> list)
        : base(list)
    {
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (SynchronizationContext.Current == _synchronizationContext)
        {
            // Execute the CollectionChanged event on the current thread
            RaiseCollectionChanged(e);
        }
        else
        {
            // Post the CollectionChanged event on the creator thread
            _synchronizationContext.Post(RaiseCollectionChanged, e);
        }
    }

    private void RaiseCollectionChanged(object param)
    {
        // We are in the creator thread, call the base implementation directly
        base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
    }

    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (SynchronizationContext.Current == _synchronizationContext)
        {
            // Execute the PropertyChanged event on the current thread
            RaisePropertyChanged(e);
        }
        else
        {
            // Post the PropertyChanged event on the creator thread
            _synchronizationContext.Post(RaisePropertyChanged, e);
        }
    }

    private void RaisePropertyChanged(object param)
    {
        // We are in the creator thread, call the base implementation directly
        base.OnPropertyChanged((PropertyChangedEventArgs)param);
    }
}

مزيد من التفاصيل يمكن العثور عليها هنا :http://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top