Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xamarin/Xamarin.PropertyEditing.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs95
-rw-r--r--Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs82
-rw-r--r--Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs23
3 files changed, 166 insertions, 34 deletions
diff --git a/Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs b/Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs
index 824e9fb..ace3fb2 100644
--- a/Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs
+++ b/Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs
@@ -936,6 +936,7 @@ namespace Xamarin.PropertyEditing.Tests
var stringVms = vm.Properties.OfType<StringPropertyViewModel> ().ToList();
Assert.That (stringVms.Count, Is.EqualTo (3), "Not including correct number of properties with variants");
Assert.That (stringVms.Count (svm => svm.Variation == null), Is.EqualTo (1), "Did not include neutral property");
+ Assert.That (stringVms.First (svm => svm.Variation == null).HasVariantChildren, Is.True, "Did not report variant children");
Assert.That (stringVms.Count (svm => svm.Variation == variants[0]), Is.EqualTo (1), "Missing variant property");
Assert.That (stringVms.Count (svm => svm.Variation == variants[1]), Is.EqualTo (1), "Missing variant property");
}
@@ -968,12 +969,17 @@ namespace Xamarin.PropertyEditing.Tests
editor.SetupGet (oe => oe.TargetType).Returns (typeof (object).ToTypeInfo ());
editor.SetupGet (oe => oe.Target).Returns (target);
editor.SetupGet (oe => oe.Properties).Returns (new[] { property.Object });
- editor.Setup (oe => oe.GetPropertyVariantsAsync (property.Object)).ReturnsAsync (new[] { variants[1] });
+ editor.Setup (oe => oe.GetPropertyVariantsAsync (property.Object)).ReturnsAsync (new[] { variants[0], variants[1] });
editor.Setup (oe => oe.GetValueAsync<string> (property.Object, null)).ReturnsAsync (
new ValueInfo<string> {
Value = "Any",
Source = ValueSource.Local
});
+ editor.Setup (oe => oe.GetValueAsync<string> (property.Object, variants[0])).ReturnsAsync (
+ new ValueInfo<string> {
+ Value = "Compact",
+ Source = ValueSource.Local
+ });
editor.Setup (oe => oe.GetValueAsync<string> (property.Object, variants[1])).ReturnsAsync (
new ValueInfo<string> {
Value = "Compact+P3",
@@ -1005,9 +1011,11 @@ namespace Xamarin.PropertyEditing.Tests
vm.SelectedObjects.Add (target);
var stringVms = vm.Properties.OfType<StringPropertyViewModel> ().ToList ();
- Assume.That (stringVms.Count, Is.EqualTo (2), "Not including correct number of properties with variants");
- Assume.That (stringVms.Count (svm => svm.Variation == null), Is.EqualTo (1), "Did not include neutral property");
- Assume.That (stringVms.Count (svm => svm.Variation == variants[1]), Is.EqualTo (1), "Missing variant property");
+ Assert.That (stringVms.Count, Is.EqualTo (3), "Not including correct number of properties with variants");
+ Assert.That (stringVms.Count (svm => svm.Variation == null), Is.EqualTo (1), "Did not include neutral property");
+ Assert.That (stringVms.First (svm => svm.Variation == null).HasVariantChildren, Is.True, "Did not report variant children");
+ Assert.That (stringVms.Count (svm => svm.Variation == variants[0]), Is.EqualTo (1), "Missing variant property");
+ Assert.That (stringVms.Count (svm => svm.Variation == variants[1]), Is.EqualTo (1), "Missing variant property");
vm.SelectedObjects.Add (target2);
@@ -1105,6 +1113,84 @@ namespace Xamarin.PropertyEditing.Tests
}
[Test]
+ public void VariantsUpdated ()
+ {
+ var variations = new[] {
+ new PropertyVariationOption ("Width", "Compact"),
+ new PropertyVariationOption ("Width", "Regular"),
+ new PropertyVariationOption ("Gamut", "P3"),
+ new PropertyVariationOption ("Gamut", "sRGB"),
+ };
+
+ var property = new Mock<IPropertyInfo> ();
+ property.SetupGet (p => p.Name).Returns ("Variation");
+ property.SetupGet (p => p.Type).Returns (typeof (string));
+ property.SetupGet (p => p.RealType).Returns (typeof (string).ToTypeInfo ());
+ property.SetupGet (p => p.CanWrite).Returns (true);
+ property.SetupGet (p => p.ValueSources).Returns (ValueSources.Default | ValueSources.Local);
+ property.SetupGet (p => p.Variations).Returns (variations);
+
+ var properties = new ObservableCollection<IPropertyInfo> { property.Object };
+
+ var variation0 = new PropertyVariation (variations[0]);
+ var variation1 = new PropertyVariation (variations[0], variations[2]);
+ var variants = new List<PropertyVariation> {
+ variation0,
+ variation1
+ };
+
+ var target = new object ();
+ var editor = new Mock<IObjectEditor> ();
+ editor.SetupGet (oe => oe.TargetType).Returns (typeof (object).ToTypeInfo ());
+ editor.SetupGet (oe => oe.Target).Returns (target);
+ editor.SetupGet (oe => oe.Properties).Returns (properties);
+ editor.Setup (oe => oe.GetPropertyVariantsAsync (property.Object)).ReturnsAsync (variants);
+ editor.Setup (oe => oe.GetValueAsync<string> (property.Object, null)).ReturnsAsync (
+ new ValueInfo<string> {
+ Value = "Any",
+ Source = ValueSource.Local
+ });
+ editor.Setup (oe => oe.GetValueAsync<string> (property.Object, variation0)).ReturnsAsync (
+ new ValueInfo<string> {
+ Value = "Compact",
+ Source = ValueSource.Local
+ });
+ editor.Setup (oe => oe.GetValueAsync<string> (property.Object, variation1)).ReturnsAsync (
+ new ValueInfo<string> {
+ Value = "Compact+P3",
+ Source = ValueSource.Local
+ });
+
+ var provider = new Mock<IEditorProvider> ();
+ provider.Setup (p => p.GetObjectEditorAsync (target)).ReturnsAsync (editor.Object);
+
+ var vm = CreateVm (provider.Object);
+ vm.SelectedObjects.Add (target);
+
+ var stringVms = vm.Properties.OfType<StringPropertyViewModel> ().ToList ();
+ Assume.That (stringVms.Count, Is.EqualTo (3), "Not including correct number of properties with variants");
+ Assume.That (stringVms.Count (svm => svm.Variation == null), Is.EqualTo (1), "Did not include neutral property");
+ Assume.That (stringVms.First (svm => svm.Variation == null).HasVariantChildren, Is.True, "Did not report variant children");
+ Assume.That (stringVms.Count (svm => svm.Variation == variants[0]), Is.EqualTo (1), "Missing variant property");
+ Assume.That (stringVms.Count (svm => svm.Variation == variants[1]), Is.EqualTo (1), "Missing variant property");
+
+ variants.RemoveAt (1);
+ editor.Raise (oe => oe.PropertyChanged += null, new EditorPropertyChangedEventArgs (property.Object));
+
+ Assert.That (vm.Properties.Count, Is.EqualTo (2));
+ Assert.That (stringVms.Count (svm => svm.Variation == null), Is.EqualTo (1), "Did not include neutral property");
+ Assert.That (stringVms.First (svm => svm.Variation == null).HasVariantChildren, Is.True, "Did not report variant children");
+ Assert.That (stringVms.Count (svm => svm.Variation == variants[0]), Is.EqualTo (1), "Missing variant property");
+
+ variants.RemoveAt (0);
+ editor.Raise (oe => oe.PropertyChanged += null, new EditorPropertyChangedEventArgs (property.Object));
+
+ Assert.That (vm.Properties.Count, Is.EqualTo (1));
+ Assert.That (stringVms.Count (svm => svm.Variation == null), Is.EqualTo (1), "Did not include neutral property");
+ Assert.That (stringVms.First (svm => svm.Variation == null).HasVariantChildren, Is.False, "Did not update variant children");
+ }
+
+ [Test]
public void VariantsAddedWhenPropertyIs ()
{
var variations = new[] {
@@ -1231,6 +1317,7 @@ namespace Xamarin.PropertyEditing.Tests
stringVms = vm.Properties.OfType<StringPropertyViewModel> ().ToList ();
Assert.That (stringVms.Count, Is.EqualTo (3), "Not including correct number of properties with variants");
Assert.That (stringVms.Count (svm => svm.Variation == null), Is.EqualTo (1), "Did not include neutral property");
+ Assert.That (stringVms.First (svm => svm.Variation == null).HasVariantChildren, Is.True, "Did not report variant children");
Assert.That (stringVms.Count (svm => svm.Variation == variants[0]), Is.EqualTo (1), "Missing variant property");
Assert.That (stringVms.Count (svm => svm.Variation == variants[1]), Is.EqualTo (1), "Missing variant property");
}
diff --git a/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs b/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs
index e97647b..9bf6bf1 100644
--- a/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs
+++ b/Xamarin.PropertyEditing/ViewModels/PropertiesViewModel.cs
@@ -167,6 +167,7 @@ namespace Xamarin.PropertyEditing.ViewModels
removedEditors = new IObjectEditor[e.OldItems.Count];
for (int i = 0; i < e.OldItems.Count; i++) {
IObjectEditor editor = this.objEditors.First (oe => oe?.Target == e.OldItems[i]);
+ editor.PropertyChanged -= OnObjectEditorPropertyChanged;
INotifyCollectionChanged notifier = editor.Properties as INotifyCollectionChanged;
if (notifier != null)
notifier.CollectionChanged -= OnObjectEditorPropertiesChanged;
@@ -181,8 +182,13 @@ namespace Xamarin.PropertyEditing.ViewModels
case NotifyCollectionChangedAction.Reset: {
removedEditors = new IObjectEditor[this.objEditors.Count];
for (int i = 0; i < removedEditors.Length; i++) {
- removedEditors[i] = this.objEditors[i];
- INotifyCollectionChanged notifier = removedEditors[i]?.Properties as INotifyCollectionChanged;
+ IObjectEditor editor = this.objEditors[i];
+ if (editor == null)
+ continue;
+
+ removedEditors[i] = editor;
+ editor.PropertyChanged -= OnObjectEditorPropertyChanged;
+ INotifyCollectionChanged notifier = editor.Properties as INotifyCollectionChanged;
if (notifier != null)
notifier.CollectionChanged -= OnObjectEditorPropertiesChanged;
}
@@ -226,20 +232,45 @@ namespace Xamarin.PropertyEditing.ViewModels
ErrorsChanged?.Invoke (this, e);
}
+ private void OnObjectEditorPropertyChanged (object sender, EditorPropertyChangedEventArgs e)
+ {
+ if (!e.Property.HasVariations ())
+ return;
+
+ OnVariationsChanged (e.Property, EventArgs.Empty);
+ }
+
private async void OnVariationsChanged (object sender, EventArgs e)
{
+ IPropertyInfo property = sender as IPropertyInfo;
+ if (property == null)
+ property = ((PropertyViewModel)sender).Property;
+
using (await AsyncWork.RequestAsyncWork (this)) {
- PropertyViewModel pvm = (PropertyViewModel) sender;
- var variations = (await GetVariationsAsync (pvm.Property)).SelectMany (vs => vs).Distinct ();
- var properties = this.editors
- .OfType<PropertyViewModel> ()
- .Where (evm => Equals (evm.Property, pvm.Property) && evm.Variation != null)
- .ToDictionary (evm => evm.Variation);
+ var variationsTask = GetVariationsAsync (property);
+
+ PropertyViewModel baseVm = null;
+ var properties = new Dictionary<PropertyVariation, PropertyViewModel> ();
+ foreach (PropertyViewModel pvm in this.editors.OfType<PropertyViewModel> ()) {
+ if (!Equals (property, pvm.Property))
+ continue;
+
+ if (pvm.Variation == null)
+ baseVm = pvm;
+ else
+ properties.Add (pvm.Variation, pvm);
+ }
+
+ if (baseVm == null)
+ throw new InvalidOperationException ("Base property view model couldn't be found");
+
+ var variations = await variationsTask;
+ baseVm.HasVariantChildren = variations.Count > 0;
List<PropertyViewModel> toAdd = new List<PropertyViewModel> ();
foreach (PropertyVariation variation in variations) {
if (!properties.Remove (variation)) {
- toAdd.Add (GetViewModel (pvm.Property, variation));
+ toAdd.Add (CreateViewModel (property, variation));
}
}
@@ -472,12 +503,11 @@ namespace Xamarin.PropertyEditing.ViewModels
List<EditorViewModel> newVms = new List<EditorViewModel> ();
foreach (IPropertyInfo property in newSet) {
if (variations != null && variations.TryGetValue (property, out Dictionary<PropertyVariation, PropertyViewModel> propertyVariations)) {
- var setVariations = (await GetVariationsAsync (property)).SelectMany (vs => vs).Distinct ();
- foreach (PropertyVariation variation in setVariations) {
+ foreach (PropertyVariation variation in await GetVariationsAsync (property)) {
if (propertyVariations.Remove (variation))
continue;
- newVms.Add (GetViewModel (property, variation));
+ newVms.Add (CreateViewModel (property, variation));
}
foreach (var kvp in propertyVariations) {
@@ -486,7 +516,7 @@ namespace Xamarin.PropertyEditing.ViewModels
} else if (property.HasVariations()) {
newVms.AddRange (await GetViewModelsAsync (property));
} else {
- newVms.Add (GetViewModel (property));
+ newVms.Add (CreateViewModel (property));
}
}
@@ -511,6 +541,7 @@ namespace Xamarin.PropertyEditing.ViewModels
if (editor == null)
continue;
+ editor.PropertyChanged += OnObjectEditorPropertyChanged;
var notifier = editor.Properties as INotifyCollectionChanged;
if (notifier != null)
notifier.CollectionChanged += OnObjectEditorPropertiesChanged;
@@ -532,35 +563,28 @@ namespace Xamarin.PropertyEditing.ViewModels
tcs.SetResult (true);
}
- private Task<IReadOnlyCollection<PropertyVariation>[]> GetVariationsAsync (IPropertyInfo property)
+ private async Task<IReadOnlyCollection<PropertyVariation>> GetVariationsAsync (IPropertyInfo property)
{
var variantTasks = new List<Task<IReadOnlyCollection<PropertyVariation>>> (ObjectEditors.Count);
for (int i = 0; i < ObjectEditors.Count; i++) {
variantTasks.Add (ObjectEditors[i].GetPropertyVariantsAsync (property));
}
- return Task.WhenAll (variantTasks);
+ return (await Task.WhenAll (variantTasks)).SelectMany (vs => vs).Distinct ().ToList ();
}
- private async Task<IReadOnlyList<PropertyViewModel>> GetViewModelsAsync (IPropertyInfo property, IEnumerable<PropertyVariation> variantsToSkip = null)
+ private async Task<IReadOnlyList<PropertyViewModel>> GetViewModelsAsync (IPropertyInfo property)
{
- PropertyViewModel baseVm = GetViewModel (property);
- List<PropertyViewModel> vms = new List<PropertyViewModel> ();
- vms.Add (baseVm);
-
- HashSet<PropertyVariation> skipped =
- (variantsToSkip != null) ? new HashSet<PropertyVariation> (variantsToSkip) : null;
+ PropertyViewModel baseVm = CreateViewModel (property);
+ var vms = new List<PropertyViewModel> { baseVm };
if (baseVm.HasVariations) {
using (await AsyncWork.RequestAsyncWork (this)) {
var variants = await GetVariationsAsync (property);
- for (int i = 0; i < variants.Length; i++) {
- foreach (PropertyVariation variant in variants[i]) {
- if (skipped != null && skipped.Contains (variant))
- continue;
+ baseVm.HasVariantChildren = variants.Count > 0;
- vms.Add (GetViewModel (property, variant));
- }
+ foreach (PropertyVariation variant in variants) {
+ vms.Add (CreateViewModel (property, variant));
}
}
}
@@ -568,7 +592,7 @@ namespace Xamarin.PropertyEditing.ViewModels
return vms;
}
- private PropertyViewModel GetViewModel (IPropertyInfo property, PropertyVariation variant = null)
+ private PropertyViewModel CreateViewModel (IPropertyInfo property, PropertyVariation variant = null)
{
PropertyViewModel vm;
Type[] interfaces = property.GetType ().GetInterfaces ();
diff --git a/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs b/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs
index 951e848..2d6319b 100644
--- a/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs
+++ b/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs
@@ -516,7 +516,7 @@ namespace Xamarin.PropertyEditing.ViewModels
private bool CanCreateVariation ()
{
- return HasVariations;
+ return HasVariations && !IsVariant;
}
private async void OnCreateVariation ()
@@ -611,8 +611,26 @@ namespace Xamarin.PropertyEditing.ViewModels
get { return Property.CanWrite && TargetPlatform.BindingProvider != null && Property.ValueSources.HasFlag (ValueSources.Binding); }
}
+ /// <summary>
+ /// Gets whether the property has possible variations.
+ /// </summary>
public bool HasVariations => Property.HasVariations();
+ public bool HasVariantChildren
+ {
+ get { return this.hasVariantChildren; }
+ internal set
+ {
+ if (this.hasVariantChildren == value)
+ return;
+
+ this.hasVariantChildren = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public bool IsVariant => Variation != null;
+
public abstract Resource Resource
{
get;
@@ -737,6 +755,8 @@ namespace Xamarin.PropertyEditing.ViewModels
try {
if (e.Property != null && !Equals (e.Property, Property))
return;
+ if (!Equals (Variation, e.Variation))
+ return;
// TODO: Smarter querying, can query the single editor and check against MultipleValues
await UpdateCurrentValueAsync ();
@@ -800,6 +820,7 @@ namespace Xamarin.PropertyEditing.ViewModels
private HashSet<IPropertyInfo> constraintProperties;
private string error;
private Task<bool> isAvailable;
+ private bool hasVariantChildren;
private void OnErrorsChanged (DataErrorsChangedEventArgs e)
{