Browse Source

CollectionElementsCollection now implements INotifyCollectionChanged. Using this in XamlProperty to know when the collection gets empty, and if conditions are fulfilled remove unnecessary xaml.

This change was necessary because before this change Reset was called on the collection property from CollectionElementsCollection. This had the unwanted effect that it caused the instance property value to use property default value, which often is null, when all we actually wanted was to avoid bloated xaml and leave the instance property value untouched.
pull/657/head
gumme 10 years ago
parent
commit
bd1981ded9
  1. 40
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs
  2. 20
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs

40
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs

@ -19,15 +19,17 @@ @@ -19,15 +19,17 @@
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace ICSharpCode.WpfDesign.XamlDom
{
/// <summary>
/// The collection used by XamlProperty.CollectionElements
/// </summary>
sealed class CollectionElementsCollection : Collection<XamlPropertyValue>
sealed class CollectionElementsCollection : Collection<XamlPropertyValue>, INotifyCollectionChanged
{
XamlProperty property;
bool isClearing = false;
internal CollectionElementsCollection(XamlProperty property)
{
@ -44,9 +46,17 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -44,9 +46,17 @@ namespace ICSharpCode.WpfDesign.XamlDom
protected override void ClearItems()
{
while (Count > 0) {
RemoveAt(Count - 1);
isClearing = true;
try {
while (Count > 0) {
RemoveAt(Count - 1);
}
} finally {
isClearing = false;
}
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
protected override void RemoveItem(int index)
@ -58,14 +68,13 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -58,14 +68,13 @@ namespace ICSharpCode.WpfDesign.XamlDom
CollectionSupport.RemoveItem(info.ReturnType, collection, propertyValue.GetValueFor(info), propertyValue);
}
this[index].RemoveNodeFromParent();
this[index].ParentProperty = null;
var item = this[index];
item.RemoveNodeFromParent();
item.ParentProperty = null;
base.RemoveItem(index);
// If item was removed from an implicit collection that is now empty we reset its property to remove markup for the property if still there.
if (Count == 0 && property.PropertyValue == null) {
property.Reset();
}
if (CollectionChanged != null && !isClearing)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
}
protected override void InsertItem(int index, XamlPropertyValue item)
@ -80,12 +89,25 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -80,12 +89,25 @@ namespace ICSharpCode.WpfDesign.XamlDom
property.InsertNodeInCollection(item.GetNodeForCollection(), index);
base.InsertItem(index, item);
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
}
protected override void SetItem(int index, XamlPropertyValue item)
{
var oldItem = this[index];
RemoveItem(index);
InsertItem(index, item);
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, oldItem, index));
}
#region INotifyCollectionChanged implementation
public event NotifyCollectionChangedEventHandler CollectionChanged;
#endregion
}
}

20
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs

@ -67,6 +67,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -67,6 +67,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
if (propertyInfo.IsCollection) {
isCollection = true;
collectionElements = new CollectionElementsCollection(this);
collectionElements.CollectionChanged += OnCollectionChanged;
if (propertyInfo.Name.Equals(XamlConstants.ResourcesPropertyName, StringComparison.Ordinal) &&
propertyInfo.ReturnType == typeof(ResourceDictionary)) {
@ -75,6 +76,25 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -75,6 +76,25 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
}
void OnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// If implicit collection that is now empty we remove markup for the property if still there.
if (collectionElements.Count == 0 && propertyValue == null && _propertyElement != null)
{
_propertyElement.ParentNode.RemoveChild(_propertyElement);
_propertyElement = null;
ParentObject.OnPropertyChanged(this);
if (IsSetChanged != null) {
IsSetChanged(this, EventArgs.Empty);
}
if (ValueChanged != null) {
ValueChanged(this, EventArgs.Empty);
}
}
}
/// <summary>
/// Gets the parent object for which this property was declared.
/// </summary>

Loading…
Cancel
Save