問題タブ [inotifycollectionchanged]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
wpf - CollectionChanged イベント ハンドラが呼び出されないのはなぜですか?
コレクション内のアイテムの内容が変更されたときにイベントを取得するために、アイテムが追加または削除されたときに各アイテムに PropertyChanged イベントハンドラーを追加するには、ObservableCollection クラスを拡張する必要があることをスタックオーバーフローに関するいくつかの調査と他の回答で示しました。 ..本当に少し面倒ですが、これらの回答のいくつかに基づいてこのクラスを実装しました:
私が理解しているように、CollectionChanged イベントは、要素の 1 つが PropertyChanged イベントを発生させるたびに発生します。item_PropertyChanged メソッドから DeeplyObservableCollection_CollectionChanged メソッドにステップ インするので、コードをステップ実行すると、これはうまくいくようです。
したがって、私のコードでは、次のようにイベント ハンドラーを DeeplyObservableCollection_CollectionChanged メソッドにアタッチします。
GroupSettingsList は DeeplyObservableCollection であり、ContentCollectionChanged は CollectionChanged イベントハンドラーです。エラーは発生しませんが、メソッドが呼び出されず、その理由がわかりません。
ここでイベント ハンドラーを呼び出すにはどうすればよいですか?
このクラスの使用方法を示す追加コード:
c# - コレクションから LINQ クエリにバインドされた UI コントロールへの変更通知を取得できません
学習中のLINQを使用して簡単な問題を解決しようとしています。
この場合はシリアル ポートを表す文字列のコレクションがあり、コントロールに表示されますが、順序付けする必要があります。元のコレクションはソートされておらず、必ずしもそれを変更したりコピーしたりする必要はありません。そこで、IEnumerable 型のプロパティを作成し、ComboBox にバインドしました。
これはうまく機能します.ComboBoxには正しいコンテンツが正しい順序で含まれています. ただし、元のコレクションが変更された場合、a) 元のコレクションが変更されたときに ComboBox が適切に通知されないか、b) LINQ クエリが更新されていません。
いくつかの異なることを試した後、次のコードがどのように機能しないかわかりません。私は何かが欠けているに違いない。
ここには冗長な余分なコードがあるかもしれません... とにかく、コントロールの XAML が続くソース:
XAML:
silverlight - コレクション内のコレクションへの Silverlight データ バインディング
うまくいけば、誰かがこれで私を助けてくれます。画像の編集に使用する Silverlight アプリを作成しています。ユーザーは、要素を含むレイヤーを含むプロジェクトを持っています。(要素は text 要素と image 要素です)。
プロジェクトを表すクラスがあります。が含まれておりObservableCollection<Layer>
、各レイヤーには がありObservableCollection<Element>
ます。要素は抽象クラスです。Element を継承する TextElement クラスと ImageElement クラスがあります。
私の問題は、コレクション内の要素を変更しても UI が更新されないことです。私はすべてのプロパティで INotifyPropertyChanged を使用しており、コレクションで CollectionChanged をキャッチしていますが、まだうまくいきません。CollectionChanged イベントはObservableCollection<Element>
、その要素の 1 つの更新時にヒットすることはありません。
これは私がもともと持っていたコードです:
void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
this.NotifyChange("Elements");
}
誰かが助けてくれれば、とても感謝しています。
c# - 計算されたプロパティの INotfyPropertyChanged の実装
私はMVVMに少し慣れていないので、疑問に思っていました
ObservableCollection<Differences> Diffs
プロパティを定義したとしましょう。次のプロパティもあります。
OnPropertyChanged
forを実装する方法がわかりませんIsSame
。これは Diff リストから暗黙的であるためです。
- List
OnCollectionChanged
イベントにアタッチして、変更されたかどうかを確認する必要がありますIsSame
か? - とにかくバッキングフィールドを使用して List を処理する必要があり
OnCollectionChanged
ますか?
どうもありがとうございました。
c# - INotifyCollectionChanged の NewItems - OfType を使用できませんデータを取得する
CollectionChanged
を実装するコレクションのイベントからいくつかのカスタム オブジェクトを取得しようとしていますINotifyCollectionChanged
。
私が直面している問題は、myItems
常に「列挙で結果が得られませんでした」ということです。
デバッグを展開するとe.NewItems.SyncRoot
、次のようになります。
明らかにデータはそこにあります。このデータを取得する方法は何ですか?
silverlight - 2 つの監視可能なコレクションを一緒にマップするにはどうすればよいですか?
興味深い問題があります。エンティティの監視可能なコレクションを公開および維持する既存のモジュールがあります。監視可能なコレクション、または他のコレクションからのアイテムの追加と削除に対応する INotifyCollectionChanged の実装が必要ですが、エンティティ自体ではなくラッパー クラス (ビュー モデル) が含まれています。
CollectionChanged イベントがどのように機能するかを浅く理解していますが、方法がわからない完全に処理するか、既存のパターンを使用したいと考えています。誰でもこれで私を助けることができますか?
c# - コレクション内の「子エンティティ」のプロパティを使用する計算されたプロパティに対して、ある種の「OnPropertyChanged」イベントをトリガーする方法はありますか?
OnPropertyChanged
コレクション内の「子エンティティ」のプロパティを使用する計算されたプロパティに対して何らかのイベントをトリガーする方法はありますか?
小さな例:
Customer プロパティを表示する DataGrid を備えた単純な WPF アプリケーションがあります。私は Entity Framework 5 の CodeFirst アプローチを使用しているため、独自の INotifyPropertyChanged 実装を使用して手動でクラスを作成しました。
同じクラスで、3 つの計算されたプロパティを作成しました。
FullName
呼び出しているため、DataGrid で自動的に更新されます。OnPropertyChanged("FullName");
TotalCars
ICollection に何かが追加または削除され
たときに自動更新するためにおそらく使用できる INotifyCollectionChanged 実装の例を見つけました: http://www.dotnetfunda.com/articles/article886-change-notification-for-objects- and-collections.aspx
しかし、ICollection ( ) 内のOnPropertyChange("TotalOpenInvoices")
プロパティ ( ) が変更されたときにトリガーする最良の方法は何ですか?PayedInFull
Invoices
Invoice クラスのようなことOnPropertyChanged("Customer.TotalOpenInvoices");
をしてもうまくいかないようです... :)
inotifycollectionchanged - ObservableCollection の CollectionChanged イベントが発生しない
私はXamDataGrid
観察可能なコレクションにバインドされている を持っています。XamDataGrid
は編集可能ですので、レコードの追加・編集・削除が可能です。CollectionChanged
&PropertyChanged
イベントを実装しました。
CollectionChanged
イベントには次のコードが含まれています。
これはすべて正常に機能しています。
以下に示す奇妙な問題があります。
グリッドにレコードを追加してグリッドから削除すると、コレクションをループしてコレクションからアイテムを削除しています
例: PhoneDetailsCollection.Remove(item);
ここで、別のレコードを追加すると、CollectionChanged
イベントが発生しません。
ここで何か見逃しましたか?どんな助けでも大歓迎です...
c# - WPF Datagrid に多くの項目を追加すると、多くの CPU 時間が消費されます
簡単なスニファー機能を持ち、ユーザーがダンプしたパケットを表示するアプリケーションを作成しています。パケットはダンプ ファイルから読み取られ、現在のトラフィックでリアルタイムに更新され、キャプチャされたパケットが Datagrid に追加されます (各パケットは新しい行です)。データ バインディングを使用して、ICollectionChanged インターフェイスを実装するダンプ リーダーからパケットを取得するため、新しいパケットごとに Datagrid に通知されます。Datagrid は、仮想化と遅延スクロールを使用します。ほとんどすべてが正常に動作します - 唯一の例外は巨大な CPU 消費です。この CPU 使用率は、すべての新しいパケット (毎秒数千) を読み取り、それらを表示用にフォーマットし、Datagrid を更新するすべてのパケット上昇 CollectionChanged イベントが原因で発生します。ソフトウェアの要件は、ユーザーがすべての新しいパケットをリアルタイムで見る必要がないことです。誰もそれらすべてに気付かないように。ユーザーは一部のパケットしか表示できず、必要に応じて適切な位置までバーを上下にスクロールして、必要なパケットを表示できます。その場合にのみ、パケットをファイルから読み取る必要があります。
問題は、できればスクロールバーを実際のパケット数にスケーリングすることによって、新しいパケットが到着したことを示すために Datagrid を毎秒更新することですが、継続的に読み取り、フォーマットして CollectionChanged を呼び出す必要はありません。これには CPU 時間がかかり、さらにバーをスクロールしないと、新しいパケットは表示されません。到着するパケットの数が通知されるので、すべてのパケットの数がわかります。
Datagrid を実際のパケット数に合わせてスケーリングするためだけに、偽のパケットを追加しようとしました (それにより、すべての新しいパケットの読み取りとフォーマットを回避しました)。バーをスクロールするとCPU使用率が低下し、パケットが読み取り専用になるため、ほとんど機能しました。しかし、しばらくすると、新しいパケットが Datagrid に追加されると、現在のビューの行がランダムに重複し始めました。それらは 1 番目、2 番目、3 番目、そして 1 番目、2 番目、3 番目と表示されました。
私もバインディングを更新しようとしました - それはうまくいきましたが、最初のアプローチよりも多くのリソースを消費したので、それを放棄しました. また、Datagrid の listcollectionview を更新しようとしました - バインディングの更新と同じ効果です。
次のことは、CollectionChanged への 1 回の呼び出しでパケットのリストを追加したかったときです。
範囲アクションがサポートされていないというエラーが発生しました。PresentationFramework.dll!System.Windows.Data.ListCollectionView.ValidateCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) によってスローされます。
そのため、パケットのリスト内のすべてのパケットに対して CollectionChanged を呼び出す必要があり、これにより CPU 使用率も増加しました。
要約すると、新しいパケット/行があることを Datagrid に通知したいので、Datagrid のスクロール バーはパケットの総数に合わせてスケーリングされますが、パケットはユーザーがバーをスクロールしたときにのみファイルから読み取られます。
私の問題を解決するためのあらゆる提案に非常に感謝しています。
言及すべき重要なことが 1 つあります。申し訳ありませんが、最初にそれについて話すのを忘れていました。私の ObservableCollection は、ある種のデータ仮想化をサポートしており、メモリには必要なパケットのみを保持します。新しいパケットが到着したら、コレクションに新しいパケットの数を通知するだけで、コレクションの Add メソッドを呼び出す必要はありません。実際にはパケットを追加しないため、実際に読み取られるパケットはありません. コレクションには、その瞬間のパケットの総数に関する情報と、実際にメモリに保持されているパケットの量が少ないため、グリッドで表示できます。パケットは必要な場合にのみオンザフライで読み取られ、表示されていない場合は解放されます。しかし、新しいパケットについてグリッドに通知するには、CollectionChanged を呼び出す必要があります (別のより良い方法はわかりません)。この呼び出しの引数で、すべての新しいパケットを提供する必要があります。そして、CollectionChanged へのこの呼び出しにより、パケットが実際に読み取られ、CPU が消費されます。スクロールバーのサイズが新しいパケットが到着したことを通知するようにグリッドを再スケーリングしたいが、パケットを読み取り、新しいパケットごとに CollectionChanged を呼び出す必要がない (これは毎秒何千回も発生する可能性がある). スクロール バーの位置が変更されたときにのみパケットを読み取るようにしたいので、各パケットを処理するコストのかかる操作は、すべてのパケットではなく、現在表示されている少数のパケットに対してのみ実行されます。
c# - ObservableCollection 要素単位の変換/射影ラッパー
WPF で ViewModel を作成する場合、ObservableCollection
(ソース コレクション) で使用可能なデータを、元の要素 (ターゲット コレクション) を拡張/制限/投影するラッパー要素のコレクションに変換する必要がある場合があります。常に元のコレクションをミラーリングします。
Select拡張メソッドと同じですが、継続的に更新されるため、WPF バインディングに使用できる点が異なります。
ソースのインデックス x に要素が追加されると、同じ要素の Wrapper がターゲット コレクションの同じインデックス x に追加されます。インデックス y の要素がソース コレクションで削除されると、インデックス y の要素がターゲット コレクションで削除されます。
があるとしObservableCollection<ClassA>
ますが、バインドする必要があるのはReadOnlyObservableCollection<ClassB>
(または同等の) です。ここでClassB
->ClassA
次のように:
私はこれを書くことができる私自身のを書くことTemplatedTransformCollectionWrapper
ができます:
TemplatedTransformCollectionWrapper は理想的INotifyCollectionChanged
には、元のラップされたコレクションのすべての可能な追加、削除、置換操作を実装し、正しく処理するすべてのコレクションをラップします。
正しく書くことは簡単ではなくTemplatedTransformCollectionWrapper
、他の誰かがすでに行っているようなことのようです。おそらく、コアフレームワークの一部でさえあります. しかし、私はそれを見つけることができません。