Jay*_*Jay 8 .net c# data-binding wpf xaml
这开始于我认为与我的实现有关的奇怪行为,我ToString()问了这个问题:当ToString()有一个协作对象时,为什么WPF数据绑定不显示文本?
事实证明这与合作者无关,并且具有可重复性.
当我绑定Label.Content到DataContext声明为接口类型的属性ToString()时,在运行时对象上调用,标签显示结果.
当我绑定TextBlock.Text到同一个属性时,ToString()永远不会被调用,也不显示任何内容.但是,如果我将声明的属性更改为接口的具体实现,它将按预期工作.
这是不是设计?如果是这样,任何想法为什么?
重现:
Run Code Online (Sandbox Code Playgroud)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"}; }
}
}
Run Code Online (Sandbox Code Playgroud)
将Window1的XAML设置为:
<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>
Run Code Online (Sandbox Code Playgroud)在Window1.xaml.cs中:
Run Code Online (Sandbox Code Playgroud)public partial class Window1 : Window { public Window1() { InitializeComponent(); DataContext = new Bar(); } }
当您运行此应用程序时,您将只看到一次文本(在顶部,在标签中).如果您将类的foo属性类型更改Bar为Foo(而不是IFoo)并再次运行该应用程序,您将在两个控件中看到该文本.
小智 8
我知道这个线程已经老了,但我找到了解决这个问题的方法.在绑定上使用StringFormat属性:
<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>
Run Code Online (Sandbox Code Playgroud)
是的你是对的。显然该ContentControl.Content属性的实现方式与该TextBlock.Text属性不同。当然,一个明显的区别是,ContentControl实际上会生成一个TextBlock为不是 aVisual且没有 . 的内容对象生成一个实例DataTemplate。事实TextBlock并非如此。它将自行渲染文本。在这两种情况下,字符串都由以下方式确定
IValueConverter如果存在于绑定中)TypeConverter)object.ToString() 看来该算法仅在步骤 3 上有所不同TextBlockContentControl正如您所展示的,。虽然ContentControl实际上解析了接口背后的对象,但它却TextBlock没有。有趣的。
我想这是你必须忍受的事情。您现在有多种选择:
ContentControl代替 aTextBlockIValueConverter并在绑定中使用它TypeConverter为您的界面