2 // System.Data.DataViewManager
\r
5 // Rodrigo Moya (rodrigo@ximian.com)
\r
6 // Tim Coleman (tim@timcoleman.com)
\r
7 // Atsushi Enomoto (atsushi@ximian.com)
\r
8 // Ivan N. Zlatev (contact@i-nz.net)
\r
10 // (C) Ximian, Inc. 2002
\r
11 // Copyright (C) Tim Coleman, 2002
\r
12 // Copyright (C) 2005 Novell Inc,
\r
16 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
\r
18 // Permission is hereby granted, free of charge, to any person obtaining
\r
19 // a copy of this software and associated documentation files (the
\r
20 // "Software"), to deal in the Software without restriction, including
\r
21 // without limitation the rights to use, copy, modify, merge, publish,
\r
22 // distribute, sublicense, and/or sell copies of the Software, and to
\r
23 // permit persons to whom the Software is furnished to do so, subject to
\r
24 // the following conditions:
\r
26 // The above copyright notice and this permission notice shall be
\r
27 // included in all copies or substantial portions of the Software.
\r
29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
30 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
31 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
32 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
33 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
34 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
35 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
39 using System.Collections;
\r
40 using System.ComponentModel;
\r
44 namespace System.Data
\r
47 /// Contains a default DataViewSettingCollection for each DataTable in a DataSet.
\r
50 [DesignerAttribute ("Microsoft.VSDesigner.Data.VS.DataViewManagerDesigner, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.IDesigner")]
\r
51 public class DataViewManager : MarshalByValueComponent, IBindingList, ICollection, IList, ITypedList, IEnumerable
\r
56 DataViewManagerListItemTypeDescriptor descriptor;
\r
57 DataViewSettingCollection settings;
\r
60 #endregion // Fields
\r
62 #region Constructors
\r
64 public DataViewManager ()
\r
69 public DataViewManager (DataSet dataSet)
\r
71 // Null argument is allowed here.
\r
72 SetDataSet (dataSet);
\r
75 #endregion // Constructors
\r
80 [DataSysDescription ("Indicates the source of data for this DataViewManager.")]
\r
82 [DefaultValue (null)]
\r
83 public DataSet DataSet {
\r
84 get { return dataSet; }
\r
87 throw new DataException ("Cannot set null DataSet.");
\r
92 public string DataViewSettingCollectionString {
\r
96 ParseSettingString (value);
\r
97 xml = BuildSettingString ();
\r
98 } catch (XmlException ex) {
\r
99 throw new DataException ("Cannot set DataViewSettingCollectionString.", ex);
\r
105 [DataSysDescription ("Indicates the sorting/filtering/state settings for any table in the corresponding DataSet.")]
\r
107 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
\r
108 public DataViewSettingCollection DataViewSettings {
\r
109 get { return settings; }
\r
112 int ICollection.Count {
\r
116 bool ICollection.IsSynchronized {
\r
117 get { return false; }
\r
120 object ICollection.SyncRoot {
\r
121 get { return this; }
\r
124 bool IList.IsFixedSize {
\r
125 get { return true; }
\r
128 bool IList.IsReadOnly {
\r
129 get { return true; }
\r
132 object IList.this [int index] {
\r
134 if (descriptor == null)
\r
135 descriptor = new DataViewManagerListItemTypeDescriptor (this);
\r
140 set { throw new ArgumentException ("Not modifiable"); }
\r
143 bool IBindingList.AllowEdit {
\r
144 get { return false; }
\r
147 bool IBindingList.AllowNew {
\r
148 get { return false; }
\r
151 bool IBindingList.AllowRemove {
\r
152 get { return false; }
\r
155 bool IBindingList.IsSorted {
\r
156 get { throw new NotSupportedException (); }
\r
159 ListSortDirection IBindingList.SortDirection {
\r
160 get { throw new NotSupportedException (); }
\r
163 PropertyDescriptor IBindingList.SortProperty {
\r
164 get { throw new NotSupportedException (); }
\r
167 bool IBindingList.SupportsChangeNotification {
\r
168 get { return true; }
\r
171 bool IBindingList.SupportsSearching {
\r
172 get { return false; }
\r
175 bool IBindingList.SupportsSorting {
\r
176 get { return false; }
\r
179 #endregion // Properties
\r
183 private void SetDataSet (DataSet ds)
\r
185 if (dataSet != null) {
\r
186 dataSet.Tables.CollectionChanged -= new CollectionChangeEventHandler (TableCollectionChanged);
\r
187 dataSet.Relations.CollectionChanged -= new CollectionChangeEventHandler (RelationCollectionChanged);
\r
191 settings = new DataViewSettingCollection (this);
\r
192 xml = BuildSettingString ();
\r
194 if (dataSet != null) {
\r
195 dataSet.Tables.CollectionChanged += new CollectionChangeEventHandler (TableCollectionChanged);
\r
196 dataSet.Relations.CollectionChanged += new CollectionChangeEventHandler (RelationCollectionChanged);
\r
200 private void ParseSettingString (string source)
\r
202 XmlTextReader xtr = new XmlTextReader (source,
\r
203 XmlNodeType.Element, null);
\r
206 if (xtr.Name != "DataViewSettingCollectionString")
\r
207 // easy way to throw the expected exception ;-)
\r
208 xtr.ReadStartElement ("DataViewSettingCollectionString");
\r
209 if (xtr.IsEmptyElement)
\r
210 return; // MS does not change the value.
\r
214 xtr.MoveToContent ();
\r
215 if (xtr.NodeType == XmlNodeType.EndElement)
\r
217 if (xtr.NodeType == XmlNodeType.Element)
\r
218 ReadTableSetting (xtr);
\r
221 } while (!xtr.EOF);
\r
222 if (xtr.NodeType == XmlNodeType.EndElement)
\r
223 xtr.ReadEndElement ();
\r
226 private void ReadTableSetting (XmlReader reader)
\r
228 // Namespace is ignored BTW.
\r
229 DataTable dt = DataSet.Tables [XmlConvert.DecodeName (
\r
230 reader.LocalName)];
\r
231 // The code below might result in NullReference error.
\r
232 DataViewSetting s = settings [dt];
\r
233 string sort = reader.GetAttribute ("Sort");
\r
235 s.Sort = sort.Trim ();
\r
236 string ads = reader.GetAttribute ("ApplyDefaultSort");
\r
237 if (ads != null && ads.Trim () == "true")
\r
238 s.ApplyDefaultSort = true;
\r
239 string rowFilter = reader.GetAttribute ("RowFilter");
\r
240 if (rowFilter != null)
\r
241 s.RowFilter = rowFilter.Trim ();
\r
242 string rsf = reader.GetAttribute ("RowStateFilter");
\r
244 s.RowStateFilter = (DataViewRowState)
\r
245 Enum.Parse (typeof (DataViewRowState),
\r
250 private string BuildSettingString ()
\r
252 if (dataSet == null)
\r
253 return String.Empty;
\r
255 StringWriter sw = new StringWriter ();
\r
257 sw.Write ("DataViewSettingCollectionString>");
\r
258 foreach (DataViewSetting s in DataViewSettings) {
\r
260 sw.Write (XmlConvert.EncodeName (
\r
261 s.Table.TableName));
\r
262 sw.Write (" Sort=\"");
\r
263 sw.Write (Escape (s.Sort));
\r
265 // LAMESPEC: MS.NET does not seem to handle this property as expected.
\r
266 if (s.ApplyDefaultSort)
\r
267 sw.Write (" ApplyDefaultSort=\"true\"");
\r
268 sw.Write (" RowFilter=\"");
\r
269 sw.Write (Escape (s.RowFilter));
\r
270 sw.Write ("\" RowStateFilter=\"");
\r
271 sw.Write (s.RowStateFilter.ToString ());
\r
274 sw.Write ("</DataViewSettingCollectionString>");
\r
275 return sw.ToString ();
\r
278 private string Escape (string s)
\r
280 return s.Replace ("&", "&")
\r
281 .Replace ("\"", """)
\r
282 .Replace ("\'", "'")
\r
283 .Replace ("<", "<")
\r
284 .Replace (">", ">");
\r
287 public DataView CreateDataView (DataTable table)
\r
289 if (settings [table] != null) {
\r
290 DataViewSetting s = settings [table];
\r
291 return new DataView (table, this, s.Sort, s.RowFilter, s.RowStateFilter);
\r
293 return new DataView (table);
\r
297 void IBindingList.AddIndex (PropertyDescriptor property)
\r
301 object IBindingList.AddNew ()
\r
303 throw new NotSupportedException ();
\r
306 void IBindingList.ApplySort (PropertyDescriptor property, ListSortDirection direction)
\r
308 throw new NotSupportedException ();
\r
311 int IBindingList.Find (PropertyDescriptor property, object key)
\r
313 throw new NotSupportedException ();
\r
316 void IBindingList.RemoveIndex (PropertyDescriptor property)
\r
320 void IBindingList.RemoveSort ()
\r
322 throw new NotSupportedException ();
\r
325 void ICollection.CopyTo (Array array, int index)
\r
327 array.SetValue (descriptor, index);
\r
330 IEnumerator IEnumerable.GetEnumerator ()
\r
332 DataViewManagerListItemTypeDescriptor[] array = new DataViewManagerListItemTypeDescriptor[((ICollection)this).Count];
\r
333 ((ICollection)this).CopyTo (array, 0);
\r
334 return array.GetEnumerator ();
\r
337 int IList.Add (object value)
\r
339 throw new ArgumentException ("Not modifiable");
\r
342 void IList.Clear ()
\r
344 throw new ArgumentException ("Not modifiable");
\r
347 bool IList.Contains (object value)
\r
349 return value == descriptor;
\r
352 int IList.IndexOf (object value)
\r
354 if (value == descriptor)
\r
359 void IList.Insert (int index, object value)
\r
361 throw new ArgumentException ("Not modifiable");
\r
364 void IList.Remove (object value)
\r
366 throw new ArgumentException ("Not modifiable");
\r
369 void IList.RemoveAt (int index)
\r
371 throw new ArgumentException ("Not modifiable");
\r
374 [MonoLimitation("Supported only empty list of listAccessors")]
\r
375 PropertyDescriptorCollection ITypedList.GetItemProperties (PropertyDescriptor[] listAccessors)
\r
377 if (dataSet == null)
\r
378 throw new DataException ("dataset is null");
\r
380 if (listAccessors == null || listAccessors.Length == 0) {
\r
381 ICustomTypeDescriptor desc = new DataViewManagerListItemTypeDescriptor (this);
\r
382 return desc.GetProperties ();
\r
385 throw new NotImplementedException ();
\r
388 string ITypedList.GetListName (PropertyDescriptor[] listAccessors)
\r
390 if (dataSet != null) {
\r
391 if (listAccessors == null || listAccessors.Length == 0)
\r
392 return dataSet.DataSetName;
\r
395 return string.Empty;
\r
398 protected virtual void OnListChanged (ListChangedEventArgs e)
\r
400 if (ListChanged != null)
\r
401 ListChanged (this, e);
\r
404 protected virtual void RelationCollectionChanged (object sender, CollectionChangeEventArgs e)
\r
406 this.OnListChanged (CollectionToListChangeEventArgs (e));
\r
409 protected virtual void TableCollectionChanged (object sender, CollectionChangeEventArgs e)
\r
411 this.OnListChanged (CollectionToListChangeEventArgs (e));
\r
414 private ListChangedEventArgs CollectionToListChangeEventArgs (CollectionChangeEventArgs e)
\r
416 ListChangedEventArgs args;
\r
418 if (e.Action == CollectionChangeAction.Remove)
\r
420 else if (e.Action == CollectionChangeAction.Refresh)
\r
421 args = new ListChangedEventArgs(ListChangedType.PropertyDescriptorChanged, null);
\r
422 else if (e.Action == CollectionChangeAction.Add)
\r
423 args = new ListChangedEventArgs(ListChangedType.PropertyDescriptorAdded, new DataRelationPropertyDescriptor(((DataRelation) e.Element)));
\r
425 args = new ListChangedEventArgs(ListChangedType.PropertyDescriptorDeleted, new DataRelationPropertyDescriptor(((DataRelation) e.Element)));
\r
430 #endregion // Methods
\r
434 public event ListChangedEventHandler ListChanged;
\r
436 #endregion // Events
\r