|
Binding to objects in WPF is easy, unless that is, you want to bind to a
specific aspect of an object such as an interface implemented by an object. It
seems that this is difficult to do especially if you've explicitly implemented
the interface. Such as in the code shown below.
public interface
IBar
{
string Plunk { get;
set; }
}
public class
Foo : IBar
{
public int
Thwack { get; set;
}
string IBar.Plunk
{ get; set; }
}
Imagine now that we want to bind to the Plunk member of the interface. We might
be tempted to write some markup like this:
<Window x:Class="Window1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<ListBox x:Name="mainList">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal" >
<TextBlock>Thwack =</TextBlock>
<TextBlock Text="{Binding Path=Thwack}"/>
<TextBlock>, Plunk =</TextBlock>
<TextBlock Text="{Binding Path=Plunk}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox >
</Grid>
</Window>
Running the program you can clearly see that the "Thwack" property is visible
and bound yet the "Plunk" property doesn't seem to exist for the purpose of
binding. We need to tell the binding where to look in greater detail.

To do this we need to provide a context for the interface. This is done by
ensuring that the namespace in which the interface resides is known to the
markup. The insertion of an XML namespace will do this:
xmlns:l="clr-namespace:WpfApplication1"
This goes in the Window1 declaration markup in the usual place. Remember though,
that if your interfaces reside in a different assembly, as well they might in a
nicely designed application, that you'll need to declare the namespace
accordingly. For example:
xmlns:src="clr-namespace:WackyNamespace.Interfaces;assembly=WackyDLL"
Once the namespace is declared you can go about telling the data-binding system
from whence the information will be gleaned.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:WpfApplication1"
Title="Window1"
Height="300" Width="300">
<Grid>
<ListBox x:Name="mainList">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal" >
<TextBlock>Thwack =</TextBlock>
<TextBlock Text="{Binding Path=Thwack}"/>
<TextBlock>, Plunk =</TextBlock>
<TextBlock Text="{Binding Path=(l:IBar.Plunk)}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox >
</Grid>
</Window>

So, there you have it. You can bind to interfaces implemented by objects; you
just need to use the correct namespace declaration and the fully qualified
binding path.
|