2012-02-08 43 views
0

ListBoxバインディングを期待どおりに動作させるのに問題があります。私は現在、ListBoxをItemの公開されたObservableCollectionのシングルトンにバインドしようとしています。アイテムは別々のクラスそのものです。現在、私は次のように結合しています:ObservableCollectionにバインドされたListBoxは更新されません

public class SomeObject : INotifyPropertyChanged 
{ 
    private Int32 m_vId; 
    private String m_vName; 

    public SomeObject() { } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(String propName) 
    { 
     if (this.PropertyChanged != null) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
     } 
    } 

    public Int32 Id 
    { 
     get { return this.m_vId; } 
     set { this.m_vId = value; NotifyPropertyChanged("Id"); } 
    } 

    public String Name 
    { 
     get { return this.m_vName; } 
     set { this.m_vName = value; NotifyPropertyChanged("Name"); } 
    } 
} 

public class SingletonClass : INotifyPropertyChanged 
{ 
    private static SingletonClass m_vInstance; 
    private ObservableCollection<SomeObject> m_vObjects; 

    private SingletonClass() 
    { 
     this.m_vObjects = new ObservableCollection<SomeObject>(); 
     for (int x = 0; x < 255; x++) 
      this.m_vObjects.Add(new SomeObject() { Id = x, Name = String.Format("{0} - new object", x) }); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(String propName) 
    { 
     if (this.PropertyChanged != null) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
     } 
    } 

    public static SingletonClass Instance 
    { 
     get 
     { 
      if (m_vInstance == null) 
       m_vInstance = new SingletonClass(); 
      return m_vInstance; 
     } 
    } 

    public ObservableCollection<SomeObject> Objects 
    { 
     get { return this.m_vObjects; } 
     set { this.m_vObjects = value; NotifyPropertyChanged("Objects"); } 
    } 
} 

現在、起動時に結合作品:

<Window x:Class="toxySharp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:classes="clr-namespace:MyApplication.Classes" 
     Title="MainWindow" Height="325" Width="400" 
     DataContext="{Binding Source={x:Static local:SingletonClass.Instance}}"> 

     <Grid x:Name="LayoutRoot"> 
      <ListBox x:Name="lstMyList" ItemsSource="{Binding Path=Objects, Mode=TwoWay}" DisplayMemberPath="Name" /> 
     </Grid> 
</Window> 

私のシングルトンは、このような基本的な実装です。アプリケーションは、各オブジェクトの名前をバインドして適切に表示します。 enter image description here

私の主な実際のアプリケーションでは、私は非同期メソッドがコレクションを更新することができますコールバックを使用します(ソケットものBeginConnect、BeginSend、など)と呼ばれているがあります。たとえば、これは同じ実装を行っているテストアプリです。 (これはプレイヤーのリストなので、特定のパケットが受信されるとそのリストでデータが更新されます)。

私の問題は、リスト上で更新されない非同期コールバックの1つの中でコレクションが更新されるときです。コレクションデータは正しく更新され、メインコードにブレークポイントを設定すると、更新されるコレクションが示されますが、リストボックスは更新されず、変更内容が反映されます。だから、同じことを言い続けているだけです。

私は何か見落としましたか?

フィルタリングを許可するためにCollectionViewSourceも使用しようとしましたが、これには同じ問題があります。私は、コレクションが初期化された方法でシングルトンにある問題を発見した

== EDITの==

。コレクションを初期化するときに内部コピーメンバを使用する代わりに、公開されたプロパティを使用してUIを更新する必要がありました。

だから、それを修正以下の使用:

private SingletonClass() 
{ 
    this.Objects = new ObservableCollection<SomeObject>(); 
    for (int x = 0; x < 255; x++) 
     this.Objects.Add(new SomeObject() { Id = x, Name = String.Format("{0} - new object", x) }); 
} 

しかし今リストは、私は、オブジェクトクラス内の別のプロパティに基づいて、これをフィルタリングできるようにしたい作品を結合することを。 (SomeObjectの例では)。オブジェクトがアクティブであるかどうかを示すbooleanがあります。 CollectionViewSourceにバインドしようとすると、更新されていない問題に戻ります。では、これを手動でフィルタリングし、uiを更新したままにする方法はありますか?

答えて

0

UpdateSourceTrigger =のPropertyChangedコレクションは、それがリストに更新されません非同期 コールバックの1の内側に更新されたときに私の問題がある

<ListBox x:Name="lstMyList" ItemsSource="{Binding Path=Objects,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" DisplayMemberPath="Name" /> 
+1

は、のItemsSourceがターゲット上で変更されることはありません、それが戻って任意の場合のソースに伝播しません。 –

+0

私はOPを正しく理解していれば、そのソースは更新されていますが、ビューはそれを見ていません。それを修正するために、更新されたourcreatrigger = propertychangedを持つ必要があります。それが何もしない場合は、 "ソース"のあなたの定義が何であるか教えてください。私の頭の中では、ビューモデルのobservablecollectionを意味します。 – Anton

+2

いいえ、 'UpdateSourceTrigger'は**他の方法で**、 'TextBox'では誰かがテキストを入力すると、' Text'がバインドされているソースをすべてのキーストロークで更新する必要があるかどうかを判断します。 'ItemsControls'は' ItemsSource'プロパティを変更せず、ユーザー入力によって変更することもできません。また、 'UpdateSourceTrigger'は決して何もしません。 –

2

が不足しています。

よく問題はありません!観察可能なコレクションはスレッドセーフではありません。あなたはそのようにする必要があります。問題は、あなたのコードでマルチスレッドであるよう

TwoWay結合様式やUpdateSourceTrigger=PropertyChanged

使用あなたの容易さのために、スレッドセーフかつ迅速に観察可能なコレクションのこのカスタム実装...この場合に役立ちます...

Fast performing and thread safe observable collection

限りINotifyPropertyChangedインタフェースに関しては、その「のPropertyChanged event is automatically dispatched to the UI thread. So any multithreaded context updating the properties of a class that implements INotifyPropertyChanged`は、GUIを更新します。このことができますなら、私を知ってみましょう

、これは全く何もしない

+0

スレッドの問題はありません。スレッドの問題が発生しないように、コールバック内の何かがメインスレッドに呼び出されていることを確認します。 – atom0s

+0

そのコードを表示できますか? –

+0

主な質問を編集しました。更新の問題の原因が見つかりました。しかし今、問題は、CollectionViewSourceへのバインディングが再び更新されない問題を引き起こすため、ソートする方法です。 – atom0s

関連する問題