This started with weird behaviour that I thought was tied to my implementation of ToString()
, and I asked this question: http://stackoverflow.com/questions/2916068/why-wont-wpf-databindings-show-text-when-tostring-has-a-collaborating-object
It turns out to have nothing to do with collaborators and is reproducible.
When I bind Label.Content
to a property of the DataContext
that is declared as an interface type, ToString()
is called on the runtime object and the label displays the result.
When I bind TextBlock.Text
to the same property, ToString()
is never called and nothing is displayed. But, if I change the declared property to a concrete implementation of the interface, it works as expected.
Is this somehow by design? If so, any idea why?
To reproduce:
- Create a new WPF Application (.NET 3.5 SP1)
- Add the following classes:
public interface IFoo { string foo_part1 { get; set; } string foo_part2 { get; set; } } public class Foo : IFoo { public string foo_part1 { get; set; } public string foo_part2 { get; set; } public override string ToString() { return foo_part1 + " - " + foo_part2; } }
public class Bar
{
public IFoo foo
{
get { return new Foo {foo_part1 = "first", foo_part2 = "second"}; }
}
}
Set the XAML of Window1 to:
<Window x:Class="WpfApplication1.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"> <StackPanel> <Label Content="{Binding foo, Mode=Default}"/> <TextBlock Text="{Binding foo, Mode=Default}"/> </StackPanel> </Window>
in Window1.xaml.cs:
public partial class Window1 : Window { public Window1() { InitializeComponent(); DataContext = new Bar(); } }
When you run this application, you'll see the text only once (at the top, in the label). If you change the type of foo
property on Bar
class to Foo
(instead of IFoo
) and run the application again, you'll see the text in both controls.