[C] MergedRD: new tests and minor fixes

This commit is contained in:
Stephane Delcroix 2017-09-13 14:53:43 +02:00
Родитель 2b7913adda
Коммит 7d90f145b7
2 изменённых файлов: 98 добавлений и 37 удалений

Просмотреть файл

@ -3,6 +3,7 @@ using System.Linq;
using NUnit.Framework;
using System.Collections.Generic;
using Xamarin.Forms.Internals;
using System.Collections.ObjectModel;
namespace Xamarin.Forms.Core.UnitTests
{
@ -410,5 +411,61 @@ namespace Xamarin.Forms.Core.UnitTests
Assert.That(rd.MergedDictionaries.Count, Is.EqualTo(0));
}
[Test]
public void AddingMergedRDTriggersValueChanged()
{
var rd = new ResourceDictionary();
var label = new Label {
Resources = rd
};
label.SetDynamicResource(Label.TextProperty, "foo");
Assert.That(label.Text, Is.EqualTo(Label.TextProperty.DefaultValue));
rd.MergedDictionaries.Add(new ResourceDictionary { { "foo", "Foo"} });
Assert.That(label.Text, Is.EqualTo("Foo"));
}
[Test]
//this is to keep the alignment with resources removed from RD
public void RemovingMergedRDDoesntTriggersValueChanged()
{
var rd = new ResourceDictionary {
MergedDictionaries = {
new ResourceDictionary {
{ "foo", "Foo" }
}
}
};
var label = new Label {
Resources = rd,
};
label.SetDynamicResource(Label.TextProperty, "foo");
Assert.That(label.Text, Is.EqualTo("Foo"));
rd.MergedDictionaries.Clear();
Assert.That(label.Text, Is.EqualTo("Foo"));
}
[Test]
public void AddingResourceInMergedRDTriggersValueChanged()
{
var rd0 = new ResourceDictionary ();
var rd = new ResourceDictionary {
MergedDictionaries = {
rd0
}
};
var label = new Label {
Resources = rd,
};
label.SetDynamicResource(Label.TextProperty, "foo");
Assert.That(label.Text, Is.EqualTo(Label.TextProperty.DefaultValue));
rd0.Add("foo", "Foo");
Assert.That(label.Text, Is.EqualTo("Foo"));
}
}
}

Просмотреть файл

@ -14,8 +14,9 @@ namespace Xamarin.Forms
{
static ConditionalWeakTable<Type, ResourceDictionary> s_instances = new ConditionalWeakTable<Type, ResourceDictionary>();
readonly Dictionary<string, object> _innerDictionary = new Dictionary<string, object>();
ResourceDictionary _mergedInstance;
Type _mergedWith;
[TypeConverter (typeof(TypeTypeConverter))]
public Type MergedWith {
get { return _mergedWith; }
@ -35,57 +36,60 @@ namespace Xamarin.Forms
}
}
ResourceDictionary _mergedInstance;
public ICollection<ResourceDictionary> MergedDictionaries { get; private set; }
public ResourceDictionary()
{
var collection = new ObservableCollection<ResourceDictionary>();
collection.CollectionChanged += MergedDictionaries_CollectionChanged;
MergedDictionaries = collection;
ICollection<ResourceDictionary> _mergedDictionaries;
public ICollection<ResourceDictionary> MergedDictionaries {
get {
if (_mergedDictionaries == null) {
var col = new ObservableCollection<ResourceDictionary>();
col.CollectionChanged += MergedDictionaries_CollectionChanged;
_mergedDictionaries = col;
}
return _mergedDictionaries;
}
}
IList<ResourceDictionary> _collectionTrack;
void MergedDictionaries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// Movement of items doesn't affect monitoring of events
// Move() isn't exposed by ICollection
if (e.Action == NotifyCollectionChangedAction.Move)
return;
// New Items
var newItems = e.NewItems?.Cast<ResourceDictionary>();
if (newItems != null)
{
foreach (var item in newItems)
{
_collectionTrack.Add(item);
item.ValuesChanged += Item_ValuesChanged;
}
if (newItems.Count() > 0)
OnValuesChanged(newItems.SelectMany(x => x).ToArray());
}
// Old Items
var oldItems = e.OldItems?.Cast<ResourceDictionary>();
if (oldItems != null)
foreach (var item in oldItems)
{
item.ValuesChanged -= Item_ValuesChanged;
_collectionTrack.Remove(item);
}
_collectionTrack = _collectionTrack ?? new List<ResourceDictionary>();
// Collection has been cleared
if (e.Action == NotifyCollectionChangedAction.Reset)
{
if (e.Action == NotifyCollectionChangedAction.Reset) {
foreach (var dictionary in _collectionTrack)
dictionary.ValuesChanged -= Item_ValuesChanged;
_collectionTrack.Clear();
return;
}
// New Items
if (e.NewItems != null)
{
foreach (var item in e.NewItems)
{
var rd = (ResourceDictionary)item;
_collectionTrack.Add(rd);
rd.ValuesChanged += Item_ValuesChanged;
OnValuesChanged(rd.ToArray());
}
}
// Old Items
if (e.OldItems != null)
{
foreach (var item in e.OldItems)
{
var rd = (ResourceDictionary)item;
rd.ValuesChanged -= Item_ValuesChanged;
_collectionTrack.Remove(rd);
}
}
}
IList<ResourceDictionary> _collectionTrack = new List<ResourceDictionary>();
void Item_ValuesChanged(object sender, ResourcesChangedEventArgs e)
{
OnValuesChanged(e.Values.ToArray());