هل هناك طريقة أفضل لإجبار البيانات المرتبطة بـ WPF ListBox على التحديث؟

StackOverflow https://stackoverflow.com/questions/253036

سؤال

لديّ WPF ListBox المرتبط بـ ObservableCollection ، عندما تتغير المجموعة ، تقوم جميع العناصر بتحديث موضعها.

يتم تخزين الموضع الجديد في المجموعة ولكن لا يتم تحديث واجهة المستخدم.لذلك أضفت ما يلي:

    void scenarioItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        ToolboxListItem.UpdatePositions();
        lstScenario.ItemsSource = null;
        lstScenario.ItemsSource = ToolboxListItem.ScenarioItems;
        this.lstScenario.SelectedIndex = e.NewStartingIndex;
    }

من خلال تعيين ItemsSource إلى قيمة خالية ثم ربطه مرة أخرى، يتم تحديث واجهة المستخدم.

ولكن ربما يكون هذا ترميزًا سيئًا للغاية :p

اقتراحات؟

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

المحلول

ولدي مربع قائمة منضم إلى خاصية الكائن الذي هو من نوع List<MyCustomType>() وأنا التحقق من أن البرمجية التالية بتحديث مربع القائمة عندما يتم تحديث قائمة.

void On_MyObjProperty_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
   MyListBox.Items.Refresh();
}

إذا كنت لا تزال تواجه مشاكل، مسح إطار الإخراج VS IDE (السيطرة + W، O) ومعرفة ما إذا كان يمكنك بقعة أية أخطاء ملزمة عنها.

نصائح أخرى

يقوم WPF بربط قائمة/مجموعة من العناصر بـ ListBox، ولكن لا يتم تحديث واجهة المستخدم بعد تحديث العناصر، تم حلها.

أنا مجرد غبي.بينما قرأت الكثير عن استخدام ObservableCollection<> بدلاً من List<>, لقد واصلت تجاهل هذا الاقتراح واتبعت اقتراحات أخرى، دون جدوى.عدت إلى كتبي وأعدت القراءة.لقد تم شرح ذلك بشكل جيد ObservableCollection<> يجب أن تستخدم لأن List<> لا يوفر INotifyCollectionChange الواجهة اللازمة لل ListBox لتحديث عرضه عند تغيير العناصر في المجموعة.

هذا هو الكود المحدث:

private ObservableCollection<StringWrapper> m_AppLog;
ObservableCollection<StringWrapper> Log { get { return m_AppLog; } }

بسيط جدًا، ولا يتطلب أي شيء آخر (على سبيل المثال.ينعش()).نظرًا لأن ObservableCollection يعتني بنفسه بتشغيل حدث التغيير، فقد تمكنت من إزالة الاستدعاء غير الضروري:

// notify bound objects
OnPropertyChanged("Log");

ObservableCollection لا يدعم التحديث بواسطة موضوع لم يقم بإنشائه.نظرًا لأنه يمكن تحديث قائمتي (سجل مرئي لإظهار الأخطاء/رسائل المعلومات الأخيرة) من سلاسل رسائل مختلفة، أقوم بإضافة ضبط الكود الخاص بي بهذه الطريقة لضمان إجراء التحديث باستخدام مرسل القائمة الخاص:

public void AddToLog(string message) {
    if (Thread.CurrentThread != Dispatcher.Thread) {
        // Need for invoke if called from a different thread
        Dispatcher.Invoke(
            DispatcherPriority.Normal, (ThreadStart)delegate() { AddToLog(message); });
    }
    else {
        // add this line at the top of the log
        m_AppLog.Insert(0, new StringWrapper(message));
        // ...

لاحظ ذلك أيضًا ObservableCollection<> لا يدعم RemoveRange() يتعارض مع List<>.يعد هذا جزءًا من التعديلات المحتملة المطلوبة عند التبديل من القائمة إلى ObservableCollection.

وأنا قد يكون وجود مشكلة مماثلة لما كنت تواجه، ولكن لست متأكدا.

وكان لي ObservableCollection<MyEntity> وListBox المنضم إليه. لكن بالنسبة لبعض <م> سبب غريب لم يتم تحديثه بلدي ListBox عندما غيرت خصائص الكائنات MyEntity في القائمة.

وبعد البحث لفترة من الوقت وجدت في الصفحة التالية وأود فقط أن أعلمك:

HTTP: / /www.wblum.org/listbind/net3/index.html

ومن وصفا جيدا جدا ما عليك القيام به للحصول على ListBox لتحديث عندما قائمة، أو الكائنات في داخلها، والتغيرات. اتمنى سوف تستفيد من هذا.

وكان لي نفس المشكلة يوم أمس، وانها قطعة كاملة من حماقة :) ... أنا لا وضع الألغام فارغة بعد الآن على الرغم من. في السيناريو الخاص بي، وأنا تعيين إلى MyList.ToArray () (بعد كل مرة أود أن أضيف إلى القائمة).

ولقد رأيت عدة "أوه، كنت بحاجة إلى استخدام ObservableList" <- محض هراء

ولقد رأيت عدة "أوه، نسميه" التجديد "<- محض هراء

يرجى أن يغفر لي upsettedness، ولكن أود أيضا أن نتوقع هذا العمل:)

وهذه هي الاشياء القديمة، ولكن استخدام ObservableCollection. إذا كنت تريد واجهة المستخدم لمعرفة التحديثات إلى خصائص في كائنات من ObservableCollection تحتاج إلى تنفيذ INotifyPropertyChanged في defenition فئة لهذا الكائن. ثم رفع الحدث الخاصية تغير في واضع كل الممتلكات.

Public Class Session
Implements INotifyPropertyChanged

Public Event PropertyChanged As PropertyChangedEventHandler _
   Implements INotifyPropertyChanged.PropertyChanged

Private Sub NotifyPropertyChanged(ByVal info As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub

Private _name As String = "No name"
''' <summary>
''' Name of Session
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Name() As String
    Get
        Return _name
    End Get
    Set(ByVal value As String)
        _name = value
        NotifyPropertyChanged("Name")
    End Set
End Property

إذا كان لديك ObservableList من الكائنات، وكنت تغيير خصائص داخل هذه الكائنات، لا ينطبق الإعلام منذ جمع لا يتغير مباشرة. لقد تم إجبار الإعلام بعد تغيير خصائص الكائن بلدي باستخدام إدراج () لإضافته بلدي الكائن المتغير إلى جمع، ثم RemoveAt () لإزالة النسخة القديمة. انها ليست جميلة، ولكنه يعمل.

للي، يبدو أشبه خطأ في مربع القائمة وListView. أنا ملزم لObservableCollection، والعناصر الموجودة في المجموعة تنفيذ INotifyPropertyChanged. يظهر UI أي عناصر إضافية عندما I حيوي اضغط بلدي زر "إضافة بند" لكن لدي السيطرة المضادة التي لا بد أن MyCollection.Count. هذا العداد زيادات تحكم في كل مرة كنت اضغط على بلدي 'إضافة بند' زر. إذا كنت تغيير طريقة العرض، يظهر مربع القائمة جميع عناصري إضافية. لذا، فإن ItemSource ملزمة للتحكم ListBox مكسورة. أخذت أيضا الحرص على عدم إنشاء MyCollection جديد في أي لحظة، وهو ما كسر ملزمة. بو هوو.

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