这开始怪异的行为,我认为是绑在我的执行中的ToString()
,我问这个问题:http://stackoverflow.com/questions/2916068/why-wont-wpf-databindings-show-text-when-tostring-has-a-collaborating-object
原来什么都没有做的合作者,是可重复的。
当我绑定 Label.Content
来的财产的DataContext
声明为接口类型,的ToString()
被称为运行时对象上,并在标签中显示结果。
当我绑定 TextBlock.Text
以相同的属性,的ToString()
不会被调用,并没有任何显示。 但是,如果我的声明的属性更改为具体实现的接口,它按预期工作。
在设计这是不知何故?如果是这样,任何想法,为什么?
要重现:
创建一个新的WPF应用程序(.NET 3.5 SP1) 添加以下类: 公共接口的IFoo
{
字符串foo_part1 {获得;组; }
字符串foo_part2 {获得;组; }
}
公共类Foo:IFoo的
{
公共字符串foo_part1 {获得;组; }
公共字符串foo_part2 {获得;组; }
公共重写字符串的ToString()
{
返回foo_part1 + - + foo_part2;
}
}
公共类酒吧
{
公共IFoo的FOO
{
{返回新的Foo {foo_part1第一次=,foo_part2 =第二}; }
}
}
设置窗口1的XAML为:
<窗口x:类=WpfApplication1.Window1
的xmlns =http://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
标题=窗口1高度=300宽度=300>
< StackPanel的>
<标签内容={结合FOO,模式=默认}/>
< TextBlock的文本={结合FOO,模式=默认}/>
< / StackPanel的>
< /窗>
在Window1.xaml.cs:
公共部分类窗口1:窗口
{
公共窗口1()
{
的InitializeComponent();
DataContext的=新的酒吧();
}
}
当您运行此应用程序,你会看到文本只有一次(在顶部,在标签)。如果您更改富
属性的类型上酒吧
类富
(而不是的IFoo
),并再次运行应用程序,你会看到两个控件中的文本。
我知道这个线程是旧的,但我发现了一个解决此问题。使用的StringFormat属性上的绑定:
<窗口x:类=WpfApplication1.Window1
的xmlns =http://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
标题=窗口1高度=300宽度=300>
< StackPanel的>
<标签内容={结合FOO,模式=默认}/>
< TextBlock的文本={结合FOO,模式=默认,的StringFormat = {} {0}}/>
< / StackPanel的>
< /窗>
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.
I know this thread is old but I found a workaround for this problem. Use the StringFormat property on the binding:
<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, StringFormat={}{0}}"/>
</StackPanel>
</Window>