diff --git a/src/Markup/Perspex.Markup/Data/CommonPropertyNames.cs b/src/Markup/Perspex.Markup/Data/CommonPropertyNames.cs
new file mode 100644
index 0000000000..5866539886
--- /dev/null
+++ b/src/Markup/Perspex.Markup/Data/CommonPropertyNames.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Perspex.Markup.Data
+{
+ public static class CommonPropertyNames
+ {
+ public const string IndexerName = "Item";
+ }
+}
diff --git a/src/Markup/Perspex.Markup/Data/IndexerNode.cs b/src/Markup/Perspex.Markup/Data/IndexerNode.cs
index 97f3b688f9..46663074e3 100644
--- a/src/Markup/Perspex.Markup/Data/IndexerNode.cs
+++ b/src/Markup/Perspex.Markup/Data/IndexerNode.cs
@@ -6,6 +6,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
+using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
@@ -40,6 +41,22 @@ namespace Perspex.Markup.Data
{
incc.CollectionChanged += CollectionChanged;
}
+
+ var inpc = target as INotifyPropertyChanged;
+
+ if(inpc != null)
+ {
+ inpc.PropertyChanged += IndexerPropertyChanged;
+ }
+ }
+
+ private void IndexerPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ var typeInfo = sender.GetType().GetTypeInfo();
+ if (typeInfo.GetDeclaredProperty(e.PropertyName).GetIndexParameters().Any())
+ {
+ CurrentValue = GetValue(sender);
+ }
}
protected override void Unsubscribe(object target)
@@ -108,17 +125,8 @@ namespace Perspex.Markup.Data
}
else
{
- PropertyInfo indexerProperty = null;
- ParameterInfo[] indexerParameters = null;
- foreach (var property in typeInfo.DeclaredProperties)
- {
- var indexParams = property.GetIndexParameters();
- if (indexParams.Length > 0)
- {
- indexerProperty = property;
- indexerParameters = indexParams;
- }
- }
+ var indexerProperty = GetIndexer(typeInfo);
+ var indexerParameters = indexerProperty?.GetIndexParameters();
if (indexerProperty != null && indexerParameters.Length == Arguments.Count)
{
var convertedObjectArray = new object[indexerParameters.Length];
@@ -138,6 +146,25 @@ namespace Perspex.Markup.Data
return PerspexProperty.UnsetValue;
}
+ private static PropertyInfo GetIndexer(TypeInfo typeInfo)
+ {
+ PropertyInfo indexer;
+ // Check for the default indexer name first to make this faster.
+ // This will only be false when a class in VB has a custom indexer name.
+ if ((indexer = typeInfo.GetDeclaredProperty(CommonPropertyNames.IndexerName)) != null)
+ {
+ return indexer;
+ }
+ foreach (var property in typeInfo.DeclaredProperties)
+ {
+ if (property.GetIndexParameters().Any())
+ {
+ return property;
+ }
+ }
+ return null;
+ }
+
private bool InBounds(int[] args, Array array)
{
if (args.Length == array.Rank)
diff --git a/src/Markup/Perspex.Markup/Perspex.Markup.csproj b/src/Markup/Perspex.Markup/Perspex.Markup.csproj
index 535fec127f..ba6e7d9331 100644
--- a/src/Markup/Perspex.Markup/Perspex.Markup.csproj
+++ b/src/Markup/Perspex.Markup/Perspex.Markup.csproj
@@ -41,6 +41,7 @@
Properties\SharedAssemblyInfo.cs
+
diff --git a/tests/Perspex.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs b/tests/Perspex.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs
index 2f54ae3758..a233586a58 100644
--- a/tests/Perspex.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs
+++ b/tests/Perspex.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs
@@ -146,5 +146,40 @@ namespace Perspex.Markup.UnitTests.Data
Assert.Equal(new[] { "bar", PerspexProperty.UnsetValue }, result);
}
+
+ [Fact]
+ public void Should_Track_NonIntegerIndexer()
+ {
+ var data = new { Foo = new NonIntegerIndexer() };
+ data.Foo["foo"] = "bar";
+ data.Foo["baz"] = "qux";
+
+ var target = new ExpressionObserver(data, "Foo[foo]");
+ var result = new List