1 //------------------------------------------------------------------------------
2 // <copyright file="Select.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
9 namespace System.Data {
12 using System.ComponentModel;
13 using System.Collections.Generic;
14 using System.Diagnostics;
16 internal sealed class DataViewListener {
18 private readonly WeakReference _dvWeak;
19 private DataTable _table;
22 /// <summary><see cref="DataView.ObjectID"/></summary>
23 internal readonly int ObjectID;
25 internal DataViewListener(DataView dv) {
26 this.ObjectID = dv.ObjectID;
27 _dvWeak = new WeakReference(dv);
30 private void ChildRelationCollectionChanged(object sender, CollectionChangeEventArgs e) {
31 DataView dv = (DataView)_dvWeak.Target;
33 dv.ChildRelationCollectionChanged(sender, e);
40 private void ParentRelationCollectionChanged(object sender, CollectionChangeEventArgs e) {
41 DataView dv = (DataView)_dvWeak.Target;
43 dv.ParentRelationCollectionChanged(sender, e);
50 private void ColumnCollectionChanged(object sender, CollectionChangeEventArgs e) {
51 DataView dv = (DataView)_dvWeak.Target;
53 dv.ColumnCollectionChangedInternal(sender, e);
61 /// Maintain the DataView before <see cref="DataView.ListChanged"/> is raised.
63 internal void MaintainDataView(ListChangedType changedType, DataRow row, bool trackAddRemove) {
64 DataView dv = (DataView)_dvWeak.Target;
66 dv.MaintainDataView(changedType, row, trackAddRemove);
73 internal void IndexListChanged(ListChangedEventArgs e) {
74 DataView dv = (DataView)_dvWeak.Target;
76 dv.IndexListChangedInternal(e);
83 internal void RegisterMetaDataEvents(DataTable table) {
84 Debug.Assert(null == _table, "DataViewListener already registered table");
87 // actively remove listeners without a target
88 RegisterListener(table);
90 // start listening to events
91 CollectionChangeEventHandler handlerCollection = new CollectionChangeEventHandler(ColumnCollectionChanged);
92 table.Columns.ColumnPropertyChanged += handlerCollection;
93 table.Columns.CollectionChanged += handlerCollection;
95 CollectionChangeEventHandler handlerChildRelation = new CollectionChangeEventHandler(ChildRelationCollectionChanged);
96 ((DataRelationCollection.DataTableRelationCollection)(table.ChildRelations)).RelationPropertyChanged += handlerChildRelation;
97 table.ChildRelations.CollectionChanged += handlerChildRelation;
99 CollectionChangeEventHandler handlerParentRelation = new CollectionChangeEventHandler(ParentRelationCollectionChanged);
100 ((DataRelationCollection.DataTableRelationCollection)(table.ParentRelations)).RelationPropertyChanged += handlerParentRelation;
101 table.ParentRelations.CollectionChanged += handlerParentRelation;
105 internal void UnregisterMetaDataEvents() {
106 UnregisterMetaDataEvents(true);
109 private void UnregisterMetaDataEvents(bool updateListeners) {
110 DataTable table = _table;
114 CollectionChangeEventHandler handlerCollection = new CollectionChangeEventHandler(ColumnCollectionChanged);
115 table.Columns.ColumnPropertyChanged -= handlerCollection;
116 table.Columns.CollectionChanged -= handlerCollection;
118 CollectionChangeEventHandler handlerChildRelation = new CollectionChangeEventHandler(ChildRelationCollectionChanged);
119 ((DataRelationCollection.DataTableRelationCollection)(table.ChildRelations)).RelationPropertyChanged -= handlerChildRelation;
120 table.ChildRelations.CollectionChanged -= handlerChildRelation;
122 CollectionChangeEventHandler handlerParentRelation = new CollectionChangeEventHandler(ParentRelationCollectionChanged);
123 ((DataRelationCollection.DataTableRelationCollection)(table.ParentRelations)).RelationPropertyChanged -= handlerParentRelation;
124 table.ParentRelations.CollectionChanged -= handlerParentRelation;
126 if (updateListeners) {
127 List<DataViewListener> listeners = table.GetListeners();
129 listeners.Remove(this);
135 internal void RegisterListChangedEvent(Index index) {
136 Debug.Assert(null == _index, "DataviewListener already registered index");
141 index.ListChangedAdd(this);
146 internal void UnregisterListChangedEvent() {
147 Index index = _index;
152 index.ListChangedRemove(this);
153 if (index.RemoveRef() <= 1) {
160 private void CleanUp(bool updateListeners) {
161 UnregisterMetaDataEvents(updateListeners);
162 UnregisterListChangedEvent();
165 private void RegisterListener(DataTable table) {
166 List<DataViewListener> listeners = table.GetListeners();
168 for (int i = listeners.Count - 1; 0 <= i; --i) {
169 DataViewListener listener = listeners[i];
170 if (!listener._dvWeak.IsAlive) {
171 listeners.RemoveAt(i);
172 listener.CleanUp(false);