Why won't WPF databindings show text when ToSt

2019-07-21 13:16发布

问题:

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.

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

  1. ToString() is called
  2. the collaborating object is not null and returns the expected result
  3. when inspected in the debugger, the objects return the expected result from 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.

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.

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?

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

回答1:

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:

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.