代码之家  ›  专栏  ›  技术社区  ›  Jay

当绑定属性声明为接口与类类型时,WPF绑定行为不同?

  •  8
  • Jay  · 技术社区  · 14 年前

    ToString() ,我问了一个问题: Why won't WPF databindings show text when ToString() has a collaborating object?

    结果证明它与合作者无关,而且是可复制的。

    当我绑定时 Label.Content 属于 DataContext ToString() 在运行时对象上调用,标签显示结果。

    TextBlock.Text 去同一个地方, ToString() 但是 ,如果我将声明的属性更改为接口的具体实现,它将按预期工作。

    这是故意的吗?如果是,你知道为什么吗?

    复制:

    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"}; } 
        }
    }
    
    • 将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>
      
    public partial class Window1 : Window  
    {  
        public Window1()  
        {  
            InitializeComponent();  
            DataContext = new Bar();  
        }  
    }
    

    foo Bar 类到 Foo IFoo )然后再次运行应用程序,您将在两个控件中看到文本。

    2 回复  |  直到 7 年前
        1
  •  8
  •   Henrik    12 年前

    我知道这个线程是旧的,但我找到了解决这个问题的方法。对绑定使用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>
    
        2
  •  3
  •   bitbonk    14 年前

    是的,你是对的。显然 ContentControl.Content TextBlock.Text 财产。当然,一个明显的区别是 ContentControl 会产生一个 TextBlock Visual DataTemplate . 这个 控件

    1. 这个 IValueConverter (如果装订中有)
    2. 这个 TypeConverter
    3. object.ToString()

    这个算法似乎只在第三步中不同 控件 内容控制 如你所示。而 内容控制 没有。很有趣。

    我想这是你必须忍受的。您现在有几个选项:

    • 内容控制 而不是 控件
    • IValueConverter公司 在装订中使用
    • 提供 类型转换器
    • 做点别的(可能还有更多)