Silverlight / WPF: is it possible to bind to an explicit interface indexer implementation?

Print Content | More

The WPF binding system allows you to bind to Indexers and properties and it also have a nice feature that allows you to bind to the explicit implementation of interfaces’ members, allowing you to resolve possible ambiguities if the properties have the same names, let’s consider this simple example you have the following two interfaces and a class that implements them:

public interface IFirst
{
   string this[string index] { get; }

   String Name { get; }
}

public interface ISecond
{
   string this[string index] { get; }

   String Name { get; }
}

public class Entity : IFirst, ISecond
{
   public string Name
   {
       get { return "Class Name"; }
   }
   
   public string this[string index]
   {
       get { return "Class Indexer"; }
   }

   string IFirst.this[string index]
   {
       get { return "First Indexer"; }
   }

   string IFirst.Name
   {
       get { return "First Name"; }
   }

   string ISecond.this[string index]
   {
       get { return "Second Indexer"; }
   }

   string ISecond.Name
   {
       get { return "Second Name"; }
   }
}

And you can bind them with a syntax like this:


   
   
   

   
   
   
   
   
   
   

If you run this code you will see the correct binding working for the first 4 textboxes:

IndexersBinding

I wasn’t able to find any binding syntax to have the explicitly implemented indexers binding work as expected, so I have to conclude that, as far as I know, this particular binding type is not yet supported (or this is a bug in the WPF binding system). If you have more info on the subject please, let me know.

Silverlight currently does not support binding to explicit interface implementations: when you try to write something similar to that the Xaml parser give you the E_UNEXPECTED error. I think this is one of the reasons why the Silverlight Team introduced a new interface for validation and error reporting like INotifyDataErrorInfo instead of just relying on the IDataErrorInfo typical to WPF: the IDataErrorInfo indexer (used to access the error’s collection) most of the time it’s implemented using explicit interface implementation; I would really like to see a porting of that interface in WPF soon cause I think it has a better design than the current IDataErrorInfo.

What you can do then? Well...nothing much about the explicit interface binding in Silverlight, it’s not supported...and you can’t write any binding extension to add it, so we just have to leave without it; you can maybe write a binding extension to fix the indexers’ binding, but that will not be applicable to Silverlight projects.

A small workaround I use is to define an interface - called IIndexable - that simply define an indexer and write an implementation class that act as a wrapper around the explicit indexer implementation I want to bind too...not much elegant, but it works in both worlds and you can restrict the access to the indexers implementing the get and set operations as needed:

public interface IIndexable
{
   TResult this[TKey index] { get; }
}

public class IndexableWrapper : IIndexable
{
   public IndexableWrapper(IFirst wrapped)
   {
       _class = wrapped;
   }

   private readonly IFirst _class;

   public string this[string index]
   {
       get { return _class[index]; }
   }
}

// in your entity class you can now add a member you can freely bind to
...
public IIndexable FirstIndexer
{
  get { return  (new IndexableWrapper(this)); }
}

You can check the solution containing the full samples just downloading this file, it contains both the WPF and the Silverlight solutions:



Binding, Indexer, Interface, Silverlight, WPF

2 comments

Related Post

  1. #1 da RichardD - Thursday July 2010 alle 05:59

    Can't you just expose the explicit interface implementations as properties?

    class Entity : IFirst, ISecond
    {
    public IFirst First { get { return this; } }
    public ISecond Second { get { return this; } }
    }

    Binding Path=First[0]
    Binding Path=Second[0]

  2. #2 da Alessandro Giorgetti - Friday July 2010 alle 03:12

    Unfortunately that will not work due to how the binding are 'resolved' by the engine, basically the binding expression is decomposed in a series of sub-sections and each section is evaluated in sequence; thus first the 'First' part of the path is resolved to the entity object, then the indexer operator is called through reflection and the the class indexer will always be called.
    This is the reason why I had to wrap the call with another interface: acting this way I'm sure that the indexer of the wrapping class will be called which in turns calls the right interface implemented indexer.

All fields are required and you must provide valid data in order to be able to comment on this post.


(will not be published)
(es: http://www.mysite.com)