/// <summary> /// This is overridden to return a property descriptors for the object represented by this type /// descriptor along with extra property descriptors for its child properties. /// </summary> /// <param name="attributes">An array of attributes to use as a filter or null for no filter</param> /// <returns>Returns a <see cref="PropertyDescriptorCollection"/> that contains property descriptors for /// the object and its child properties.</returns> public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // This seems to ignore the filter so GetChildProperties() will get rid of all non-browsable // properties. PropertyDescriptorCollection props = base.GetProperties(attributes); List<PropertyDescriptor> newProps = new List<PropertyDescriptor>(); this.GetChildProperties(null, String.Empty, attributes, props, newProps); if(newProps.Count != 0) { // The collection is read-only so we'll need to create a new one PropertyDescriptor[] tempProps = new PropertyDescriptor[props.Count + newProps.Count]; props.CopyTo(tempProps, 0); newProps.CopyTo(tempProps, props.Count); props = new PropertyDescriptorCollection(tempProps); // Now we'll remove hidden top-level properties for(int idx = 0; idx < props.Count; idx++) if(props[idx].Attributes[typeof(HidePropertyAttribute)] != null) { props.RemoveAt(idx); idx--; } } return props; }
private void AssertReadOnly (PropertyDescriptorCollection descriptors, string testCase) { MockPropertyDescriptor mockPropertyDescr = new MockPropertyDescriptor ( "Date", DateTime.Now); try { descriptors.Add (mockPropertyDescr); Assert.Fail (testCase + "#1"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { descriptors.Add (null); Assert.Fail (testCase + "#2"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { descriptors.Clear (); Assert.Fail (testCase + "#3"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { descriptors.Insert (0, mockPropertyDescr); Assert.Fail (testCase + "#4"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { descriptors.Insert (0, null); Assert.Fail (testCase + "#5"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { descriptors.Remove (mockPropertyDescr); Assert.Fail (testCase + "#6"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { descriptors.Remove (null); Assert.Fail (testCase + "#7"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { descriptors.RemoveAt (0); Assert.Fail (testCase + "#8"); } catch (NotSupportedException) { // read-only collection cannot be modified } IList list = (IList) descriptors; Assert.IsTrue (((IList) descriptors).IsReadOnly, testCase + "#9"); Assert.IsTrue (((IList) descriptors).IsFixedSize, testCase + "#10"); try { list.Add (mockPropertyDescr); Assert.Fail (testCase + "#11"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { list.Add (null); Assert.Fail (testCase + "#12"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list.Clear (); Assert.Fail (testCase + "#13"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list.Insert (0, mockPropertyDescr); Assert.Fail (testCase + "#14"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { list.Insert (0, null); Assert.Fail (testCase + "#15"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list.Remove (mockPropertyDescr); Assert.Fail (testCase + "#16"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { list.Remove (null); Assert.Fail (testCase + "#17"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list.RemoveAt (0); Assert.Fail (testCase + "#18"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list[0] = mockPropertyDescr; Assert.Fail (testCase + "#19"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { list[0] = null; Assert.Fail (testCase + "#20"); } catch (NotSupportedException) { // read-only collection cannot be modified } IDictionary dictionary = (IDictionary) descriptors; Assert.IsTrue (dictionary.IsReadOnly, testCase + "#21"); Assert.IsTrue (dictionary.IsFixedSize, testCase + "#22"); try { dictionary.Add ("test", mockPropertyDescr); Assert.Fail (testCase + "#23"); } catch (NotSupportedException) { // read-only collection cannot be modified } // value is checked before read-only check try { dictionary.Add ("test", null); Assert.Fail (testCase + "#24"); } catch (ArgumentException) { // read-only collection cannot be modified } try { dictionary.Clear (); Assert.Fail (testCase + "#25"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { dictionary[0] = mockPropertyDescr; Assert.Fail (testCase + "#26"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { dictionary[0] = null; Assert.Fail (testCase + "#27"); } catch (NotSupportedException) { // read-only collection cannot be modified } }