33

ObservableCollection にバインドされた WPF ListBox があります。コレクションが変更されると、すべての項目がその位置を更新します。

新しい位置はコレクションに保存されますが、UI は更新されません。だから私は以下を追加しました:

    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 を null に設定して再度バインドすると、UI が更新され、

しかし、これはおそらく非常に悪いコーディングです:p

提案?

4

8 に答える 8

77

タイプのオブジェクト プロパティにバインドされた Listbox がありList<MyCustomType>()、List が更新されると、次のコードがリスト ボックスを更新することを確認しました。

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

問題が解決しない場合は、VS IDE の出力ウィンドウ (Ctrl+W、O) をスキャンして、報告されたバインド エラーを見つけることができるかどうかを確認してください。

于 2008-10-31T12:15:24.623 に答える
11

リスト/アイテムのコレクションをListBoxにバインドするWPFですが、アイテムが更新された後、UIが更新されません。解決しました。

私はただ愚かです。ObservableCollection<>の代わりに使用することについて多くのことを読みましたがList<>、私はこの提案を無視し続け、他の提案に従いましたが、役に立ちませんでした。私の本に戻って読み直してください。コレクション内のアイテムが変更されたときに表示を更新するために必要なインターフェイスが提供されていないため、これはObservableCollection<>使用する必要があることはかなりよく説明されています。List<>INotifyCollectionChangeListBox

これは更新されたコードです:

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

非常にシンプルで、他に何も必要ありません(Refresh()など)。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<>サポートされていないことに注意してください。これは、ListからObservableCollectionに切り替えるときに必要となる可能性のある調整の一部です。RemoveRange()List<>

于 2009-12-05T10:33:47.477 に答える
6

私はあなたが抱えているものと同様の問題を抱えているかもしれませんが、よくわかりません。

私はそれObservableCollection<MyEntity>ListBox縛られていました。しかし、何らかの奇妙な理由で、リスト内ListBoxのオブジェクトのプロパティを変更したときに更新されませんでした。MyEntity

しばらく検索したところ、次のページを見つけたので、お知らせする必要がありました。

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

ListBoxこれは、リストまたはその中のオブジェクトが変更されたときに を更新するために何をしなければならないかについての非常に良い説明です。あなたがこれから恩恵を受けることを願っています。

于 2010-11-09T21:55:01.127 に答える
4

私は昨日同じ問題を抱えていましたが、それは完全にがらくたです:) ...私はもうnullに設定していません。私のシナリオでは、それを MyList.ToArray() に設定しています(リストに追加するたびに)。

複数の「ああ、ObservableListを使用する必要があります」<--完全ながらくた。

複数の「ああ、'Refresh' を呼び出してください」<-- 完全ながらくたを見てきました。

私の動揺を許してください、しかし私はこれがうまくいくことも期待しています:)

于 2008-10-31T10:32:35.287 に答える
2

これは古いものですが、ObservableCollection を使用してください。UI に ObservableCollection のオブジェクトのプロパティの更新を表示させたい場合は、そのオブジェクトのクラス定義に INotifyPropertyChanged を実装する必要があります。次に、各プロパティのセッターでプロパティ変更イベントを発生させます。

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
于 2010-04-13T15:14:48.960 に答える
0

オブジェクトの ObservableList があり、それらのオブジェクト内のプロパティを変更している場合、コレクションは直接変更されないため、通知は適用されません。Insert() を使用して変更したオブジェクトをコレクションに再追加し、次に RemoveAt() を使用して古いコピーを削除することで、オブジェクトのプロパティを変更した後に通知を強制しています。きれいではありませんが、機能します。

于 2009-04-26T02:12:45.843 に答える