当ToString()有一个协作对象时,为什么WPF databindings不显示文本?

时间:2023-01-29 21:12:21

In a simple form, I bind to a number of different objects -- some go in listboxes; some in textblocks.

在一个简单的表单中,我绑定到许多不同的对象——有些在列表框中;一些版面。

A couple of these objects have collaborating objects upon which the ToString() method calls when doing its work -- typically a formatter of some kind.

这些对象中有几个具有协作对象,在执行任务时ToString()方法调用它们——通常是某种形式的格式化程序。

When I step through the code I see that when the databinding is being set up,

当我遍历代码时,我看到在设置数据库时,

  1. ToString() is called
  2. 调用ToString()
  3. the collaborating object is not null and returns the expected result
  4. 协作对象不是null,并返回预期的结果。
  5. when inspected in the debugger, the objects return the expected result from ToString()
  6. 在调试器中检查时,对象返回ToString()的预期结果

BUT the text does not show up in the form.

但是文本没有显示在表单中。

The only common thread I see is that these use a collaborating object, whereas the other bindings that show up as expected simply work from properties and methods of the containing object.

我看到的唯一的公共线程是这些线程使用协作对象,而其他按预期显示的绑定只使用包含对象的属性和方法。

If this is confusing, here is the gist in code:

如果这让人困惑,下面是代码的要点:

public class ThisThingWorks
{
    private SomeObject some_object;

    public ThisThingWorks(SomeObject s) { some_object = s; }

    public override string ToString() { return some_object.name; }
}

public class ThisDoesntWork
{
    private Formatter formatter;
    private SomeObject some_object;

    public ThisDoesntWork(SomeObject o, Formatter f) 
    {
        formatter = f; 
        some_object = o;
    }

    public override string ToString()
    {
        return formatter.Format(some_object.name);
    }
}

Again, let me reiterate -- the ToString() method works in every other context -- but when I bind to the object in WPF and expect it to display the result of ToString(), I get nothing.

同样,让我重申一下——ToString()方法在其他上下文中都适用——但是当我绑定到WPF中的对象并期望它显示ToString()结果时,我什么也得不到。

Update:

The issue seems to be what I see as a buggy behaviour in the TextBlock binding. If I bind the Text property to a property of the DataContext that is declared as an interface type, ToString() is never called. If I change the property declaration to an implementation of the interface, it works as expected. Other controls, like Label work fine when binding the Content property to a DataContext property declared as either the implementation or the interface.

这个问题似乎是我在TextBlock绑定中看到的错误行为。如果我将文本属性绑定到声明为接口类型的DataContext的属性,则不会调用ToString()。如果我将属性声明更改为接口的实现,它将按预期工作。其他控件(如Label)在将内容属性绑定到声明为实现或接口的DataContext属性时运行良好。

Because this is so far removed from the title and content of this question, I've created a new question here: WPF binding behaviour different when bound property is declared as interface vs class type?

由于这个问题与这个问题的标题和内容已经完全不同,所以我在这里创建了一个新的问题:当绑定属性被声明为接口vs类类型时,WPF绑定行为会有所不同吗?

changed the title: WPF binding behaviour different when bound property is declared as interface vs class type?

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

1 个解决方案

#1


0  

Try these simple changes:

试试这些简单的变化:

First test your program with this version of the method:

首先用这个版本的方法测试你的程序:

public override string ToString()
{
    return "This method's really being called."
}

If that actually displays something in the UI, now try this version:

如果它在UI中显示了一些东西,现在试试这个版本:

public override string ToString()
{
    Console.WriteLine(
       string.Format("some_object.name = {0}, formatter.Format(some_object.name) = {1}",
          some_object.name,
          formatter.Format(some_object.name));
    return formatter.Format(some_object.name);
}

If this doesn't lead you to figure out what's really wrong, I'll be extremely surprised.

如果这并不能让你找出真正的问题,我会非常惊讶。

#1


0  

Try these simple changes:

试试这些简单的变化:

First test your program with this version of the method:

首先用这个版本的方法测试你的程序:

public override string ToString()
{
    return "This method's really being called."
}

If that actually displays something in the UI, now try this version:

如果它在UI中显示了一些东西,现在试试这个版本:

public override string ToString()
{
    Console.WriteLine(
       string.Format("some_object.name = {0}, formatter.Format(some_object.name) = {1}",
          some_object.name,
          formatter.Format(some_object.name));
    return formatter.Format(some_object.name);
}

If this doesn't lead you to figure out what's really wrong, I'll be extremely surprised.

如果这并不能让你找出真正的问题,我会非常惊讶。