Over a million developers have joined DZone.

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

· Mobile Zone

Learn how to Deliver Better Mobile Apps Faster with Continuous Quality by managing the complexities of testing multiple devices and scenarios with this whitepaper from Perfecto Mobile.

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:

<stackpanel>
   <textbox text="{Binding Path=Name, Mode=OneWay}">
   <textbox text="{Binding Path=(local:IFirst.Name), Mode=OneWay}">
   <textbox text="{Binding Path=(local:ISecond.Name), Mode=OneWay}">

   <textbox text="{Binding Path=[0], Mode=OneWay}">
   <!--binding attempt 1 -->
   <textbox text="{Binding Path=(local:IFirst)[0], Mode=OneWay}">
   <textbox text="{Binding Path=(local:ISecond)[0], Mode=OneWay}">
   <!--binding attempt 2 -->
   <textbox text="{Binding Path=(local:IFirst.Item)[0], Mode=OneWay}">
   <textbox text="{Binding Path=(local:ISecond.Item)[0], Mode=OneWay}">
</textbox></textbox></textbox></textbox></textbox></textbox></textbox></textbox></stackpanel>

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<in out="" tresult="">
{
   TResult this[TKey index] { get; }
}

public class IndexableWrapper : IIndexable<string, string="">
{
   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<string, string=""> FirstIndexer
{
  get { return  (new IndexableWrapper(this)); }
}</string,></string,></in>

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

 



Do you know Why Apps Succeed? Perfecto Mobile analyzed over 1,000 responses to their Digial Quality Strategies survey and aim to answer the question, "Why do apps succeed?" in this exclusive report.

Topics:

Published at DZone with permission of Alessandro Giorgetti, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}